deepstrike 0.2.74__tar.gz → 0.2.75__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. {deepstrike-0.2.74 → deepstrike-0.2.75}/Cargo.lock +7 -6
  2. {deepstrike-0.2.74 → deepstrike-0.2.75}/Cargo.toml +3 -3
  3. {deepstrike-0.2.74 → deepstrike-0.2.75}/PKG-INFO +1 -1
  4. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/manager.rs +11 -0
  5. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/partitions.rs +23 -0
  6. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/governance/pipeline.rs +21 -0
  7. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/mm/memory.rs +107 -0
  8. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/chain_validator/mod.rs +3 -0
  9. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/observation.rs +8 -0
  10. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/command.rs +24 -0
  11. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/config.rs +57 -8
  12. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/crash_point.rs +2 -0
  13. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/driver/effects.rs +33 -0
  14. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/driver/events.rs +44 -5
  15. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/driver/syscall.rs +71 -27
  16. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/driver/tests.rs +573 -13
  17. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/driver.rs +59 -17
  18. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/effect.rs +15 -0
  19. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/event.rs +4 -0
  20. deepstrike-0.2.75/crates/deepstrike-core/src/runtime/kernel/wire/memory_authority.rs +174 -0
  21. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/projection.rs +2 -2
  22. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/root.rs +7 -0
  23. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/scalar.rs +5 -0
  24. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire.rs +1 -0
  25. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/state_machine/mod.rs +69 -0
  26. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-py/src/lib.rs +9 -0
  27. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/__init__.py +2 -1
  28. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/governance.py +26 -38
  29. deepstrike-0.2.75/deepstrike/memory/authority.py +62 -0
  30. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/anthropic_adapter.py +4 -2
  31. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/base.py +7 -5
  32. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/openai.py +7 -4
  33. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/openai_chat_adapter.py +3 -1
  34. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/openai_responses.py +3 -1
  35. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/qwen.py +5 -4
  36. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/stream.py +3 -0
  37. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/canonical_kernel_step.py +341 -93
  38. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/execution_plane.py +7 -1
  39. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/kernel_journal.py +23 -1
  40. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/kernel_step.py +6 -3
  41. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/mcp_proxy_plane.py +4 -1
  42. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/remote_vpc_plane.py +4 -1
  43. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/replay_provider.py +8 -1
  44. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/runner.py +468 -298
  45. deepstrike-0.2.75/deepstrike/runtime/tool_arguments.py +66 -0
  46. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/types/agent.py +10 -56
  47. {deepstrike-0.2.74 → deepstrike-0.2.75}/pyproject.toml +1 -1
  48. {deepstrike-0.2.74 → deepstrike-0.2.75}/LICENSE +0 -0
  49. {deepstrike-0.2.74 → deepstrike-0.2.75}/README.md +0 -0
  50. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/Cargo.toml +0 -0
  51. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/LICENSE +0 -0
  52. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/benches/kernel_baseline.rs +0 -0
  53. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/benches/verifiable_baseline.rs +0 -0
  54. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/benches/wait_index_baseline.rs +0 -0
  55. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/benchmark/mod.rs +0 -0
  56. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/bin/deepstrike.rs +0 -0
  57. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/bin/support/evidence_io.rs +0 -0
  58. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/compression.rs +0 -0
  59. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/config.rs +0 -0
  60. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/execution.rs +0 -0
  61. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/fault.rs +0 -0
  62. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/measurement.rs +0 -0
  63. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/mod.rs +0 -0
  64. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/policy.rs +0 -0
  65. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/pressure.rs +0 -0
  66. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/renderer.rs +0 -0
  67. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/renewal.rs +0 -0
  68. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/skill_catalog.rs +0 -0
  69. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/summarizer.rs +0 -0
  70. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/task_state.rs +0 -0
  71. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/text.rs +0 -0
  72. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/token_engine.rs +0 -0
  73. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/units.rs +0 -0
  74. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/context/utility.rs +0 -0
  75. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/evolution.rs +0 -0
  76. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/governance/constraint.rs +0 -0
  77. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/governance/mod.rs +0 -0
  78. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/governance/permission.rs +0 -0
  79. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/governance/quota.rs +0 -0
  80. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/governance/rate_limit.rs +0 -0
  81. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/governance/repeat_fuse.rs +0 -0
  82. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/governance/veto.rs +0 -0
  83. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/harness/eval.rs +0 -0
  84. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/harness/mod.rs +0 -0
  85. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/lexical.rs +0 -0
  86. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/lib.rs +0 -0
  87. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/memory/curator.rs +0 -0
  88. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/memory/durable.rs +0 -0
  89. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/memory/mod.rs +0 -0
  90. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/mm/handle.rs +0 -0
  91. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/mm/mod.rs +0 -0
  92. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/mm/value.rs +0 -0
  93. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/orchestration/mod.rs +0 -0
  94. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/orchestration/task_graph.rs +0 -0
  95. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/orchestration/tournament.rs +0 -0
  96. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/orchestration/workflow/mod.rs +0 -0
  97. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/orchestration/workflow/run.rs +0 -0
  98. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/proc/mod.rs +0 -0
  99. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/projection_pairs.rs +0 -0
  100. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/event_log.rs +0 -0
  101. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/binding.rs +0 -0
  102. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/checkpoint.rs +0 -0
  103. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/driver/continuation.rs +0 -0
  104. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/driver/planning.rs +0 -0
  105. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/driver/projection.rs +0 -0
  106. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/driver/provider.rs +0 -0
  107. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/envelope.rs +0 -0
  108. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/fault.rs +0 -0
  109. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/record.rs +0 -0
  110. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/restore.rs +0 -0
  111. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/syscall.rs +0 -0
  112. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/terminal.rs +0 -0
  113. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/tests.rs +0 -0
  114. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel/wire/transaction.rs +0 -0
  115. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/kernel.rs +0 -0
  116. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/mod.rs +0 -0
  117. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/repair.rs +0 -0
  118. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/replay.rs +0 -0
  119. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/session.rs +0 -0
  120. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/runtime/verifiable.rs +0 -0
  121. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/budget_grant.rs +0 -0
  122. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/cross_operation.rs +0 -0
  123. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/entropy.rs +0 -0
  124. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/mailbox.rs +0 -0
  125. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/milestone.rs +0 -0
  126. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/mod.rs +0 -0
  127. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/policy.rs +0 -0
  128. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/rollback.rs +0 -0
  129. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/runnable.rs +0 -0
  130. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/state_machine/cancellation.rs +0 -0
  131. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/state_machine/capability.rs +0 -0
  132. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/state_machine/eviction.rs +0 -0
  133. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/state_machine/gate.rs +0 -0
  134. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/state_machine/milestone_exec.rs +0 -0
  135. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/state_machine/process.rs +0 -0
  136. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/state_machine/signal.rs +0 -0
  137. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/state_machine/tests.rs +0 -0
  138. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/state_machine/workflow.rs +0 -0
  139. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/tcb.rs +0 -0
  140. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/scheduler/wait_index.rs +0 -0
  141. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/signals/attention.rs +0 -0
  142. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/signals/mod.rs +0 -0
  143. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/signals/queue.rs +0 -0
  144. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/signals/router.rs +0 -0
  145. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/syscall/mod.rs +0 -0
  146. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/agent.rs +0 -0
  147. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/capability.rs +0 -0
  148. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/contract.rs +0 -0
  149. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/durable_content.rs +0 -0
  150. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/error.rs +0 -0
  151. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/message.rs +0 -0
  152. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/milestone.rs +0 -0
  153. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/mod.rs +0 -0
  154. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/policy.rs +0 -0
  155. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/result.rs +0 -0
  156. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/signal.rs +0 -0
  157. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/skill.rs +0 -0
  158. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-core/src/types/task.rs +0 -0
  159. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-py/Cargo.toml +0 -0
  160. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-py/LICENSE +0 -0
  161. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-tokenizer/Cargo.toml +0 -0
  162. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-tokenizer/LICENSE +0 -0
  163. {deepstrike-0.2.74 → deepstrike-0.2.75}/crates/deepstrike-tokenizer/src/lib.rs +0 -0
  164. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/agent.py +0 -0
  165. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/collaboration/__init__.py +0 -0
  166. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/collaboration/contract.py +0 -0
  167. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/collaboration/handoff.py +0 -0
  168. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/collaboration/harness.py +0 -0
  169. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/collaboration/modes.py +0 -0
  170. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/collaboration/pool.py +0 -0
  171. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/harness/__init__.py +0 -0
  172. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/harness/harness.py +0 -0
  173. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/harness/judge.py +0 -0
  174. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/kernel/__init__.py +0 -0
  175. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/kernel/canonical.py +0 -0
  176. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/knowledge/__init__.py +0 -0
  177. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/knowledge/source.py +0 -0
  178. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/memory/__init__.py +0 -0
  179. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/memory/agent.py +0 -0
  180. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/memory/durable.py +0 -0
  181. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/memory/extraction.py +0 -0
  182. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/memory/in_memory_store.py +0 -0
  183. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/memory/protocols.py +0 -0
  184. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/memory/ranking.py +0 -0
  185. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/memory/retention.py +0 -0
  186. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/memory/working.py +0 -0
  187. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/__init__.py +0 -0
  188. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/anthropic.py +0 -0
  189. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/anthropic_compatible.py +0 -0
  190. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/capability_router.py +0 -0
  191. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/credentials.py +0 -0
  192. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/embedding.py +0 -0
  193. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/factories.py +0 -0
  194. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/fallback.py +0 -0
  195. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/gemini.py +0 -0
  196. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/gemini_adapter.py +0 -0
  197. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/model_catalog.py +0 -0
  198. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/model_registry.py +0 -0
  199. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/ollama.py +0 -0
  200. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/ollama_adapter.py +0 -0
  201. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/prepared_request.py +0 -0
  202. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/protocol_adapter.py +0 -0
  203. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/protocols.py +0 -0
  204. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/provider_error.py +0 -0
  205. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/replay.py +0 -0
  206. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/replay_validator.py +0 -0
  207. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/request_plan.py +0 -0
  208. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/runtime_registry.py +0 -0
  209. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/stop_reason.py +0 -0
  210. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/usage.py +0 -0
  211. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/providers/vendor_profiles.py +0 -0
  212. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/__init__.py +0 -0
  213. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/agent_declaration.py +0 -0
  214. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/archive.py +0 -0
  215. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/context.py +0 -0
  216. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/context_policy.py +0 -0
  217. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/credential_vault.py +0 -0
  218. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/durable_content.py +0 -0
  219. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/eval.py +0 -0
  220. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/eval_dataset.py +0 -0
  221. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/event_stream.py +0 -0
  222. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/evolution.py +0 -0
  223. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/execution_evidence.py +0 -0
  224. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/facade.py +0 -0
  225. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/filtered_plane.py +0 -0
  226. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/kernel_event_log.py +0 -0
  227. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/loop_driver.py +0 -0
  228. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/os_profile.py +0 -0
  229. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/os_snapshot.py +0 -0
  230. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/output_schema.py +0 -0
  231. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/payload_store.py +0 -0
  232. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/process_sandbox_plane.py +0 -0
  233. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/provider_replay.py +0 -0
  234. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/reaction_checkpoint.py +0 -0
  235. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/reactive_session.py +0 -0
  236. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/reducers.py +0 -0
  237. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/reliability.py +0 -0
  238. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/replay_fixture.py +0 -0
  239. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/replay_sanitize.py +0 -0
  240. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/run_group.py +0 -0
  241. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/session_log.py +0 -0
  242. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/session_repair.py +0 -0
  243. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/sub_agent_orchestrator.py +0 -0
  244. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/turn_policy.py +0 -0
  245. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/verifiable_report.py +0 -0
  246. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/workflow_control_flow.py +0 -0
  247. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/workflow_replay.py +0 -0
  248. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/workflow_store.py +0 -0
  249. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/runtime/worktree_plane.py +0 -0
  250. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/safety/__init__.py +0 -0
  251. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/safety/permissions.py +0 -0
  252. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/signals/__init__.py +0 -0
  253. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/signals/gateway.py +0 -0
  254. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/signals/scheduled.py +0 -0
  255. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/signals/types.py +0 -0
  256. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/skills/__init__.py +0 -0
  257. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/skills/loader.py +0 -0
  258. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/skills/registry.py +0 -0
  259. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/skills/watcher.py +0 -0
  260. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/tools/__init__.py +0 -0
  261. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/tools/builtin/__init__.py +0 -0
  262. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/tools/builtin/read_file.py +0 -0
  263. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/tools/errors.py +0 -0
  264. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/tools/execution.py +0 -0
  265. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/tools/registry.py +0 -0
  266. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/types/__init__.py +0 -0
  267. {deepstrike-0.2.74 → deepstrike-0.2.75}/deepstrike/types/content.py +0 -0
  268. {deepstrike-0.2.74 → deepstrike-0.2.75}/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.74"
257
+ version = "0.2.75"
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.74"
271
+ version = "0.2.75"
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.74"
283
+ version = "0.2.75"
284
284
  dependencies = [
285
285
  "compact_str",
286
286
  "deepstrike-core",
@@ -291,10 +291,11 @@ dependencies = [
291
291
 
292
292
  [[package]]
293
293
  name = "deepstrike-sdk"
294
- version = "0.2.74"
294
+ version = "0.2.75"
295
295
  dependencies = [
296
296
  "async-stream",
297
297
  "async-trait",
298
+ "base64 0.22.1",
298
299
  "bytes",
299
300
  "compact_str",
300
301
  "deepstrike-core",
@@ -327,7 +328,7 @@ dependencies = [
327
328
 
328
329
  [[package]]
329
330
  name = "deepstrike-tokenizer"
330
- version = "0.2.74"
331
+ version = "0.2.75"
331
332
  dependencies = [
332
333
  "pretty_assertions",
333
334
  "tiktoken-rs",
@@ -335,7 +336,7 @@ dependencies = [
335
336
 
336
337
  [[package]]
337
338
  name = "deepstrike-wasm"
338
- version = "0.2.74"
339
+ version = "0.2.75"
339
340
  dependencies = [
340
341
  "compact_str",
341
342
  "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.74"
6
+ version = "0.2.75"
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.74" }
12
- deepstrike-tokenizer = { path = "crates/deepstrike-tokenizer", version = "0.2.74" }
11
+ deepstrike-core = { path = "crates/deepstrike-core", version = "0.2.75" }
12
+ deepstrike-tokenizer = { path = "crates/deepstrike-tokenizer", version = "0.2.75" }
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.74
3
+ Version: 0.2.75
4
4
  Requires-Dist: httpx>=0.27
5
5
  Requires-Dist: pyyaml>=6.0
6
6
  Requires-Dist: anyio>=4.0
@@ -994,6 +994,17 @@ impl ContextManager {
994
994
  .is_none()
995
995
  }
996
996
 
997
+ /// A refused `skill` activation: withdraw the `skill:<name>` knowledge the host staged for it,
998
+ /// unless the skill is already active under an earlier admission.
999
+ pub fn retract_refused_skill(&mut self, name: &str) -> bool {
1000
+ if self.active_skills.contains_key(name) {
1001
+ return false;
1002
+ }
1003
+ self.partitions
1004
+ .knowledge
1005
+ .retract_staged(&format!("skill:{name}"))
1006
+ }
1007
+
997
1008
  /// K3: deactivate a skill — the toolset re-widens at the next `emit_call_llm` (an epoch event,
998
1009
  /// same cache cost class as activation) and the skill's `skill:<name>` knowledge pin is marked
999
1010
  /// for the next boundary sweep. Errs-open: not-active is a no-op (returns false).
@@ -209,6 +209,29 @@ impl KnowledgePartition {
209
209
  }))
210
210
  }
211
211
 
212
+ /// Withdraw content staged under `key` for something the kernel then refused (a skill whose
213
+ /// activation was rejected). A freshly appended entry has never been rendered, so it is dropped
214
+ /// outright; an existing entry keeps its rendered bytes, loses the staged upsert, and leaves at
215
+ /// the next boundary. Returns whether anything was withdrawn.
216
+ pub fn retract_staged(&mut self, key: &str) -> bool {
217
+ let Some(index) = self
218
+ .entries
219
+ .iter()
220
+ .position(|entry| entry.key.as_deref() == Some(key))
221
+ else {
222
+ return false;
223
+ };
224
+ let entry = &mut self.entries[index];
225
+ if entry.pending.take().is_some() {
226
+ entry.evict_at_boundary = true;
227
+ return true;
228
+ }
229
+ let tokens = entry.tokens;
230
+ self.entries.remove(index);
231
+ self.token_count = self.token_count.saturating_sub(tokens);
232
+ true
233
+ }
234
+
212
235
  /// Mark the keyed entry for removal at the next boundary. Errs-open: unknown key is a no-op.
213
236
  /// Returns whether a matching entry was marked.
214
237
  pub fn remove(&mut self, key: &str) -> bool {
@@ -14,6 +14,8 @@ pub struct GovernancePipeline {
14
14
  pub veto: VetoAuthority,
15
15
  pub rate_limiter: RateLimiter,
16
16
  pub constraints: ConstraintValidator,
17
+ /// Withhold statically denied tools from the provider surface (see [`Self::denies_tool`]).
18
+ pub hide_denied_tools: bool,
17
19
  }
18
20
 
19
21
  fn severity(v: &GovernanceVerdict) -> u8 {
@@ -32,9 +34,28 @@ impl GovernancePipeline {
32
34
  veto: VetoAuthority::new(),
33
35
  rate_limiter: RateLimiter::default(),
34
36
  constraints: ConstraintValidator::new(),
37
+ hide_denied_tools: false,
35
38
  }
36
39
  }
37
40
 
41
+ /// Whether every call to `name` is denied regardless of its arguments or timing — a veto or a
42
+ /// `deny` permission. Argument constraints and rate limits are per-call, and `ask_user` is a
43
+ /// runtime decision, so none of them make a tool statically unusable.
44
+ pub fn denies_tool(&self, name: &str) -> bool {
45
+ let probe = ToolCall {
46
+ id: "governance-surface".into(),
47
+ name: name.into(),
48
+ arguments: serde_json::Value::Null,
49
+ };
50
+ matches!(
51
+ self.veto.check(&probe),
52
+ Some(GovernanceVerdict::Deny { .. })
53
+ ) || matches!(
54
+ self.permission.check(&probe),
55
+ Some(GovernanceVerdict::Deny { .. })
56
+ )
57
+ }
58
+
38
59
  /// Set the current timestamp for rate limiting.
39
60
  pub fn set_time(&mut self, now_ms: u64) {
40
61
  self.rate_limiter.set_time(now_ms);
@@ -393,6 +393,65 @@ pub struct MemoryRecallLifecycle {
393
393
  pub last_recalled_at: u64,
394
394
  }
395
395
 
396
+ /// What the host's store holds for one record it just recalled — the only input the recall
397
+ /// lifecycle needs. The store reports state; it never reports the *next* state.
398
+ #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
399
+ #[serde(deny_unknown_fields)]
400
+ pub struct MemoryRecallPrior {
401
+ pub record_id: String,
402
+ #[serde(default)]
403
+ pub recall_count: u64,
404
+ #[serde(default)]
405
+ pub pinned: bool,
406
+ }
407
+
408
+ /// A recalled record whose count crossed the promotion threshold on this recall (M4).
409
+ #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
410
+ #[serde(deny_unknown_fields)]
411
+ pub struct MemoryPromotion {
412
+ pub record_id: String,
413
+ pub recall_count: u64,
414
+ }
415
+
416
+ /// M3/M4 · the one derivation of a recall's lifecycle, shared by the model's `query_memory`
417
+ /// syscall and every host recall route.
418
+ ///
419
+ /// Each distinct record counts once per derivation however many hits named it, so a prefetch that
420
+ /// issues several overlapping queries cannot inflate a count. Promotion is edge-triggered — it is
421
+ /// suggested on the recall that crosses the threshold, never again on later ones — and a pinned
422
+ /// record is never suggested, because it is already where a promotion would put it.
423
+ pub fn derive_recall_lifecycle(
424
+ priors: &[MemoryRecallPrior],
425
+ recalled_at: u64,
426
+ promotion_threshold: Option<u64>,
427
+ ) -> (Vec<MemoryRecallLifecycle>, Vec<MemoryPromotion>) {
428
+ let mut seen = std::collections::BTreeSet::new();
429
+ let mut recalls = Vec::with_capacity(priors.len());
430
+ let mut promotions = Vec::new();
431
+ for prior in priors {
432
+ if !seen.insert(prior.record_id.as_str()) {
433
+ continue;
434
+ }
435
+ let recall_count = prior.recall_count.saturating_add(1);
436
+ recalls.push(MemoryRecallLifecycle {
437
+ record_id: prior.record_id.clone(),
438
+ recall_count,
439
+ last_recalled_at: recalled_at,
440
+ });
441
+ if let Some(threshold) = promotion_threshold
442
+ && !prior.pinned
443
+ && prior.recall_count < threshold
444
+ && recall_count >= threshold
445
+ {
446
+ promotions.push(MemoryPromotion {
447
+ record_id: prior.record_id.clone(),
448
+ recall_count,
449
+ });
450
+ }
451
+ }
452
+ (recalls, promotions)
453
+ }
454
+
396
455
  /// Memory validation error.
397
456
  #[derive(Debug, Clone, Serialize, Deserialize)]
398
457
  #[serde(tag = "error_kind", rename_all = "snake_case")]
@@ -770,4 +829,52 @@ mod tests {
770
829
  ));
771
830
  assert_eq!(store.len(), 1);
772
831
  }
832
+
833
+ fn prior(record_id: &str, recall_count: u64, pinned: bool) -> MemoryRecallPrior {
834
+ MemoryRecallPrior {
835
+ record_id: record_id.into(),
836
+ recall_count,
837
+ pinned,
838
+ }
839
+ }
840
+
841
+ #[test]
842
+ fn a_recall_counts_each_record_once_and_suggests_promotion_only_on_the_crossing() {
843
+ let (recalls, promotions) = derive_recall_lifecycle(
844
+ &[
845
+ prior("crossing", 2, false),
846
+ prior("crossing", 2, false),
847
+ prior("already_past", 3, false),
848
+ prior("pinned", 2, true),
849
+ prior("fresh", 0, false),
850
+ ],
851
+ 42,
852
+ Some(3),
853
+ );
854
+ assert_eq!(
855
+ recalls
856
+ .iter()
857
+ .map(|recall| (recall.record_id.as_str(), recall.recall_count))
858
+ .collect::<Vec<_>>(),
859
+ vec![
860
+ ("crossing", 3),
861
+ ("already_past", 4),
862
+ ("pinned", 3),
863
+ ("fresh", 1)
864
+ ]
865
+ );
866
+ assert!(recalls.iter().all(|recall| recall.last_recalled_at == 42));
867
+ assert_eq!(
868
+ promotions,
869
+ vec![MemoryPromotion {
870
+ record_id: "crossing".into(),
871
+ recall_count: 3
872
+ }]
873
+ );
874
+ assert!(
875
+ derive_recall_lifecycle(&[prior("crossing", 2, false)], 1, None)
876
+ .1
877
+ .is_empty()
878
+ );
879
+ }
773
880
  }
@@ -2097,6 +2097,8 @@ mod tests {
2097
2097
  ),
2098
2098
  tokens: Some(64),
2099
2099
  tool_call_id: None,
2100
+ is_error: false,
2101
+ tool_calls: Vec::new(),
2100
2102
  })
2101
2103
  .collect(),
2102
2104
  ..InitialContext::default()
@@ -2184,6 +2186,7 @@ mod tests {
2184
2186
  Vec::new()
2185
2187
  },
2186
2188
  tool_call_id: None,
2189
+ is_error: false,
2187
2190
  tokens: None,
2188
2191
  },
2189
2192
  observed_input_tokens: None,
@@ -76,6 +76,14 @@ pub enum KernelObservation {
76
76
  subject: Option<String>,
77
77
  reason: String,
78
78
  },
79
+ /// A model `skill` syscall the kernel admitted. Hosts pin the skill's content only on this
80
+ /// fact, never on the raw call: activation is a capability mutation the kernel adjudicates.
81
+ SkillAdmitted {
82
+ turn: u32,
83
+ name: String,
84
+ #[serde(default, skip_serializing_if = "Option::is_none")]
85
+ expires_at_turn: Option<u32>,
86
+ },
79
87
  CapabilityChanged {
80
88
  turn: u32,
81
89
  #[serde(default, skip_serializing_if = "Vec::is_empty")]
@@ -43,6 +43,12 @@ pub enum HostCommand {
43
43
  ApplySkillActivation(ApplySkillActivationCommand),
44
44
  ApplyPolicyPatch(ApplyPolicyPatchCommand),
45
45
  UpdateDeadline(UpdateDeadlineCommand),
46
+ /// §22.13 · a memory write the host authored while this operation runs (a session extract, a
47
+ /// semantic archive summary). The host still performs the I/O; the kernel is the one that says
48
+ /// whether the write may happen, by the same validation rule and the same rolling write quota
49
+ /// the model's `write_memory` syscall answers to. A refusal is journaled as
50
+ /// `memory_validation_failed`; an admitted write journals nothing and the host persists it.
51
+ AdmitMemoryWrite(AdmitMemoryWriteCommand),
46
52
  }
47
53
 
48
54
  /// Cancellation. The operation id lives in the envelope and is **not** repeated here: the
@@ -181,6 +187,16 @@ pub struct SeedKnowledgeCommand {
181
187
  pub entries: Vec<KnowledgeEntry>,
182
188
  }
183
189
 
190
+ #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
191
+ #[serde(deny_unknown_fields)]
192
+ pub struct AdmitMemoryWriteCommand {
193
+ /// The host's record id, named by the audit fact when the write is refused.
194
+ pub record_id: String,
195
+ pub name: String,
196
+ /// UTF-8 byte length of the content the host intends to persist.
197
+ pub content_bytes: u32,
198
+ }
199
+
184
200
  /// §13.2 · skill activation state. Both directions in one command so a swap is atomic.
185
201
  #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
186
202
  #[serde(deny_unknown_fields)]
@@ -265,6 +281,11 @@ pub struct GovernancePolicy {
265
281
  pub rate_limits: Vec<RateLimitSpec>,
266
282
  #[serde(default, skip_serializing_if = "Vec::is_empty")]
267
283
  pub constraints: Vec<ParamConstraint>,
284
+ /// Withhold tools this policy statically denies (veto or `deny` permission) from the provider
285
+ /// surface, and say so once in the knowledge slot. The kernel decides the hidden set with the
286
+ /// same rules that enforce the calls, so the surface and the gate cannot disagree.
287
+ #[serde(default, skip_serializing_if = "Option::is_none")]
288
+ pub hide_denied_tools: Option<bool>,
268
289
  }
269
290
 
270
291
  /// Per-tool rolling-window rate limit.
@@ -558,6 +579,9 @@ impl LivePolicyPatch {
558
579
  next.governance_policy.vetoed_tools = policy.vetoed_tools.clone();
559
580
  next.governance_policy.rate_limits = policy.rate_limits.clone();
560
581
  next.governance_policy.constraints = policy.constraints.clone();
582
+ next.governance_policy.hide_denied_tools = policy
583
+ .hide_denied_tools
584
+ .unwrap_or(current.governance_policy.hide_denied_tools);
561
585
  super::config::validate_governance(
562
586
  &next.governance_policy,
563
587
  current.kernel_limits.collection_limits.governance_rules,
@@ -659,6 +659,8 @@ pub struct ResolvedGovernancePolicy {
659
659
  pub vetoed_tools: Vec<String>,
660
660
  pub rate_limits: Vec<super::command::RateLimitSpec>,
661
661
  pub constraints: Vec<super::command::ParamConstraint>,
662
+ #[serde(default, skip_serializing_if = "std::ops::Not::not")]
663
+ pub hide_denied_tools: bool,
662
664
  }
663
665
 
664
666
  #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
@@ -831,6 +833,56 @@ pub struct ResolvedMemoryPolicy {
831
833
  pub promotion_recall_threshold: Option<WireU64>,
832
834
  }
833
835
 
836
+ impl ResolvedMemoryPolicy {
837
+ /// The baseline every operation starts from, and the policy a host without a live operation
838
+ /// is judged by when it names none.
839
+ pub const DEFAULT: Self = Self {
840
+ stale_warning_days: 2,
841
+ retrieval_top_k: 5,
842
+ validation_enabled: true,
843
+ max_content_bytes: 10_000,
844
+ max_name_length: 100,
845
+ promotion_recall_threshold: None,
846
+ };
847
+
848
+ /// §22.13 · the one admission rule for a memory write, whoever proposes it.
849
+ ///
850
+ /// The model's `write_memory` syscall, a host write inside a live operation and a host write
851
+ /// with no operation at all are judged by this function and nothing else — historically each
852
+ /// SDK carried its own copy, and the copies disagreed about bytes versus characters, about
853
+ /// which fields were required, and about whether the model's path was checked at all.
854
+ ///
855
+ /// The content is judged by its UTF-8 byte length, so a host need not ship a body across the
856
+ /// boundary just to have it measured.
857
+ pub fn check_write(&self, name: &str, content_bytes: usize) -> Result<(), String> {
858
+ if !self.validation_enabled {
859
+ return Ok(());
860
+ }
861
+ if name.trim().is_empty() {
862
+ return Err("memory name must not be empty".to_string());
863
+ }
864
+ if name.chars().count() > self.max_name_length as usize {
865
+ return Err(format!(
866
+ "memory name exceeds {} characters",
867
+ self.max_name_length
868
+ ));
869
+ }
870
+ if content_bytes > self.max_content_bytes as usize {
871
+ return Err(format!(
872
+ "memory content exceeds {} bytes",
873
+ self.max_content_bytes
874
+ ));
875
+ }
876
+ Ok(())
877
+ }
878
+
879
+ /// The same resolution an operation's genesis applies, for a host that holds a policy but no
880
+ /// live operation: absent fields fall back to [`Self::DEFAULT`] and the same invariants hold.
881
+ pub fn resolve(policy: Option<&MemoryPolicy>) -> Result<Self, WireRejection> {
882
+ resolve_memory_policy(policy, &Self::DEFAULT)
883
+ }
884
+ }
885
+
834
886
  #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
835
887
  #[serde(deny_unknown_fields)]
836
888
  pub struct ResolvedFeaturePolicy {
@@ -887,6 +939,7 @@ impl ConfigDefaults {
887
939
  vetoed_tools: Vec::new(),
888
940
  rate_limits: Vec::new(),
889
941
  constraints: Vec::new(),
942
+ hide_denied_tools: false,
890
943
  },
891
944
  scheduler_policy: ResolvedSchedulerPolicy {
892
945
  critical_path_weight: 1_000_000,
@@ -948,14 +1001,7 @@ impl ConfigDefaults {
948
1001
  },
949
1002
  },
950
1003
  memory_access: None,
951
- memory_policy: ResolvedMemoryPolicy {
952
- stale_warning_days: 2,
953
- retrieval_top_k: 5,
954
- validation_enabled: true,
955
- max_content_bytes: 10_000,
956
- max_name_length: 100,
957
- promotion_recall_threshold: None,
958
- },
1004
+ memory_policy: ResolvedMemoryPolicy::DEFAULT,
959
1005
  tool_catalog: Vec::new(),
960
1006
  skill_catalog: Vec::new(),
961
1007
  verification_contracts: Vec::new(),
@@ -1525,6 +1571,7 @@ fn resolve_governance(
1525
1571
  resolved.vetoed_tools = policy.vetoed_tools.clone();
1526
1572
  resolved.rate_limits = policy.rate_limits.clone();
1527
1573
  resolved.constraints = policy.constraints.clone();
1574
+ resolved.hide_denied_tools = policy.hide_denied_tools.unwrap_or(false);
1528
1575
  }
1529
1576
  validate_governance(&resolved, rule_bound)?;
1530
1577
  Ok(resolved)
@@ -2150,6 +2197,7 @@ mod tests {
2150
2197
  tool: "write".to_string(),
2151
2198
  param_path: "destination".to_string(),
2152
2199
  })],
2200
+ hide_denied_tools: None,
2153
2201
  }),
2154
2202
  scheduler_policy: Some(SchedulerPolicy {
2155
2203
  critical_path_weight: Some(900_000),
@@ -2440,6 +2488,7 @@ mod tests {
2440
2488
  window_ms: WireU64::new(1_000),
2441
2489
  }],
2442
2490
  constraints: Vec::new(),
2491
+ hide_denied_tools: None,
2443
2492
  },
2444
2493
  }),
2445
2494
  LivePolicyPatch::TightenResourceQuota(TightenResourceQuota {
@@ -342,6 +342,7 @@ fn provider_result(
342
342
  content: String::new(),
343
343
  tool_calls: calls,
344
344
  tool_call_id: None,
345
+ is_error: false,
345
346
  tokens: None,
346
347
  },
347
348
  observed_input_tokens: None,
@@ -394,6 +395,7 @@ fn provider_answer(id: &str, at: u64, effect: &EffectId, text: &str) -> WireEnve
394
395
  content: text.to_string(),
395
396
  tool_calls: Vec::new(),
396
397
  tool_call_id: None,
398
+ is_error: false,
397
399
  tokens: None,
398
400
  },
399
401
  observed_input_tokens: None,
@@ -136,7 +136,13 @@ impl CanonicalOperationDriver {
136
136
  };
137
137
  let turn = self.engine_mut()?.turn;
138
138
  let mut recalled = Vec::with_capacity(queried.recalls.len());
139
+ let mut priors = Vec::with_capacity(queried.recalls.len());
139
140
  for recall in &queried.recalls {
141
+ priors.push(crate::mm::memory::MemoryRecallPrior {
142
+ record_id: recall.record_ref.as_str().to_string(),
143
+ recall_count: recall.recall_count.get(),
144
+ pinned: recall.pinned,
145
+ });
140
146
  // §22.13 · the host answers with records, never with authority: the recall is
141
147
  // rendered into history as content the model reads, and nothing about it
142
148
  // rewrites this operation's binding, trust or provenance.
@@ -173,6 +179,33 @@ impl CanonicalOperationDriver {
173
179
  requested_k: query.requested_k as usize,
174
180
  requires_async_response: false,
175
181
  });
182
+ // M3/M4 · the recall lifecycle is derived here, from what the store reported it held,
183
+ // and journaled — the host mirrors these counts and never computes them.
184
+ let (recalls, promotions) = crate::mm::memory::derive_recall_lifecycle(
185
+ &priors,
186
+ context.input.observed_at_ms.get(),
187
+ context
188
+ .config
189
+ .memory_policy
190
+ .promotion_recall_threshold
191
+ .map(|threshold| threshold.get()),
192
+ );
193
+ if !recalls.is_empty() {
194
+ engine.observations.push(KernelObservation::MemoryRecalled {
195
+ turn,
196
+ scope: binding_scope(&query.binding_id),
197
+ recalls,
198
+ });
199
+ }
200
+ for promotion in promotions {
201
+ engine
202
+ .observations
203
+ .push(KernelObservation::PromotionSuggested {
204
+ turn,
205
+ record_id: promotion.record_id,
206
+ recall_count: promotion.recall_count,
207
+ });
208
+ }
176
209
  let mut step = self.continue_after(context, action, root_kind)?;
177
210
  step.focus = self.focus.clone();
178
211
  Ok(step)
@@ -410,18 +410,51 @@ impl CanonicalOperationDriver {
410
410
  HostCommand::RecordDynamicWorkflowReplay(fact) => {
411
411
  self.plan_dynamic_workflow_replay(context, fact)
412
412
  }
413
- HostCommand::CompleteDynamicWorkflow(_) => {
414
- self.plan_dynamic_workflow_complete(context)
415
- }
413
+ HostCommand::CompleteDynamicWorkflow(_) => self.plan_dynamic_workflow_complete(context),
416
414
  HostCommand::ApplyCapabilityPatch(patch) => self.plan_capability_patch(patch),
417
415
  HostCommand::ApplyKnowledgeMutation(mutation) => self.plan_knowledge_mutation(mutation),
418
416
  HostCommand::SeedKnowledge(seed) => self.plan_seed_knowledge(seed),
419
417
  HostCommand::ApplySkillActivation(activation) => self.plan_skill_activation(activation),
420
418
  HostCommand::ApplyPolicyPatch(patch) => self.plan_policy_patch(patch),
421
419
  HostCommand::UpdateDeadline(deadline) => self.plan_update_deadline(deadline),
420
+ HostCommand::AdmitMemoryWrite(admit) => self.plan_admit_memory_write(context, admit),
422
421
  }
423
422
  }
424
423
 
424
+ /// §22.13 · admit a host-authored memory write by the rule the model's proposals obey.
425
+ ///
426
+ /// Validation runs before metering, exactly as on the syscall path, so a write the policy
427
+ /// refuses spends no quota. The refusal is an audit fact rather than a fault: the content is
428
+ /// usually model-derived (an extraction, a summary), so a refused write is expected behaviour
429
+ /// and not a host bug.
430
+ pub(super) fn plan_admit_memory_write(
431
+ &mut self,
432
+ context: &PlanContext<'_>,
433
+ admit: &AdmitMemoryWriteCommand,
434
+ ) -> Result<PlannedStep, KernelFault> {
435
+ let policy = context.config.memory_policy;
436
+ let engine = self.engine_mut()?;
437
+ let refusal = match policy.check_write(&admit.name, admit.content_bytes as usize) {
438
+ Err(error) => Some(error),
439
+ Ok(()) => {
440
+ let disposition = engine.gate_memory_write_proposal();
441
+ (!disposition.is_allowed())
442
+ .then(|| denial_reason(&disposition, "memory write denied"))
443
+ }
444
+ };
445
+ if let Some(error) = refusal {
446
+ let turn = engine.turn;
447
+ engine
448
+ .observations
449
+ .push(KernelObservation::MemoryValidationFailed {
450
+ turn,
451
+ record_id: admit.record_id.clone(),
452
+ error,
453
+ });
454
+ }
455
+ Ok(self.quiet_step())
456
+ }
457
+
425
458
  /// Grow a root dynamic workflow from the host controller while keeping the same kernel-owned
426
459
  /// DAG, quota ledger, trust coercion, and spawn queue as model-authored workflow growth. The
427
460
  /// host command is only admitted for an active root workflow; it cannot bootstrap or stack a
@@ -475,7 +508,10 @@ impl CanonicalOperationDriver {
475
508
  {
476
509
  return Err(KernelFault::new(
477
510
  KernelFaultCode::InvalidConfig,
478
- format!("dynamic workflow plan node {:?} cannot depend on itself", planned.node_id),
511
+ format!(
512
+ "dynamic workflow plan node {:?} cannot depend on itself",
513
+ planned.node_id
514
+ ),
479
515
  ));
480
516
  }
481
517
  }
@@ -485,6 +521,7 @@ impl CanonicalOperationDriver {
485
521
  nodes: append.nodes.clone(),
486
522
  };
487
523
  let core_spec = build_core_spec(&wire_spec)?;
524
+ ensure_fresh_node_ids(&self.node_ids, &wire_spec.nodes)?;
488
525
  let node_ids = wire_node_ids(&wire_spec);
489
526
  // A host append is the explicit append operation, even though the underlying DAG is the
490
527
  // same one used by model-authored workflow growth. Keeping the `SubmitNodes` gate and
@@ -591,7 +628,9 @@ impl CanonicalOperationDriver {
591
628
  ) -> Result<PlannedStep, KernelFault> {
592
629
  if self.root_kind != Some(RootKind::Workflow)
593
630
  || !self.engine().is_some_and(LoopStateMachine::workflow_active)
594
- || !self.engine().is_some_and(LoopStateMachine::is_dynamic_workflow_open)
631
+ || !self
632
+ .engine()
633
+ .is_some_and(LoopStateMachine::is_dynamic_workflow_open)
595
634
  {
596
635
  return Err(KernelFault::new(
597
636
  KernelFaultCode::InvalidAuthority,