bantamkit 0.36.2__tar.gz → 0.37.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. {bantamkit-0.36.2 → bantamkit-0.37.0}/PKG-INFO +14 -17
  2. {bantamkit-0.36.2 → bantamkit-0.37.0}/README.md +12 -15
  3. bantamkit-0.37.0/_assets/skills/memory-queries.md +12 -0
  4. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/skills/memory.md +7 -0
  5. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/memory_compact.json +1 -1
  6. bantamkit-0.37.0/_assets/tools/memory_queries.json +92 -0
  7. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/memory_recall.json +11 -4
  8. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/memory_save.json +14 -0
  9. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/shiftwork_status.json +26 -1
  10. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/__init__.py +1 -1
  11. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/eventlog.py +31 -13
  12. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/hookadapter.py +373 -45
  13. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/hostinstall.py +15 -0
  14. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/mcpserver.py +216 -15
  15. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/memory/__main__.py +1 -1
  16. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/memory/component.py +687 -80
  17. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/memory/divergence.py +3 -2
  18. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/memory/dream.py +19 -0
  19. bantamkit-0.37.0/src/bantamkit/memory/native.py +209 -0
  20. bantamkit-0.37.0/src/bantamkit/memory/queries.py +248 -0
  21. bantamkit-0.37.0/src/bantamkit/memory/retrieval.py +476 -0
  22. bantamkit-0.37.0/src/bantamkit/memory/skills.py +238 -0
  23. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/memory/store.py +847 -86
  24. bantamkit-0.37.0/src/bantamkit/memory/usage.py +342 -0
  25. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/shiftwork.py +13 -3
  26. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/skillaudit.py +139 -49
  27. bantamkit-0.37.0/src/bantamkit/skilldraft.py +671 -0
  28. bantamkit-0.37.0/src/bantamkit/skillfile.py +621 -0
  29. bantamkit-0.37.0/src/bantamkit/skillhost.py +369 -0
  30. bantamkit-0.37.0/src/bantamkit/skillinstall.py +1482 -0
  31. bantamkit-0.37.0/src/bantamkit/skillmine.py +1844 -0
  32. bantamkit-0.37.0/src/bantamkit/skillpromote.py +382 -0
  33. bantamkit-0.37.0/src/bantamkit/skillpropose.py +795 -0
  34. bantamkit-0.37.0/src/bantamkit/skillreport.py +603 -0
  35. bantamkit-0.37.0/src/bantamkit/storage/__init__.py +20 -0
  36. bantamkit-0.37.0/src/bantamkit/storage/coldindex.py +308 -0
  37. bantamkit-0.37.0/src/bantamkit/storage/hotindex.py +1002 -0
  38. bantamkit-0.37.0/src/bantamkit/storage/lock.py +75 -0
  39. bantamkit-0.37.0/src/bantamkit/storage/logsegment.py +394 -0
  40. bantamkit-0.37.0/src/bantamkit/storage/retention.py +838 -0
  41. bantamkit-0.37.0/src/bantamkit/storage/tiers.py +207 -0
  42. bantamkit-0.37.0/src/bantamkit/touch/__init__.py +89 -0
  43. bantamkit-0.37.0/src/bantamkit/touch/bashturn.py +91 -0
  44. bantamkit-0.37.0/src/bantamkit/touch/context.py +112 -0
  45. bantamkit-0.37.0/src/bantamkit/touch/graph.py +214 -0
  46. bantamkit-0.37.0/src/bantamkit/touch/log.py +351 -0
  47. bantamkit-0.37.0/src/bantamkit/touch/recallfile.py +99 -0
  48. bantamkit-0.37.0/src/bantamkit/touch/refs.py +105 -0
  49. bantamkit-0.37.0/src/bantamkit/touch/repo.py +335 -0
  50. bantamkit-0.37.0/src/bantamkit/touch/summary.py +196 -0
  51. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/conftest.py +62 -0
  52. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/served-tool-surface.json +142 -7
  53. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_build_identity.py +1 -0
  54. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_conformance_suite_table_gate.py +7 -1
  55. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_docread_ceilings.py +5 -2
  56. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_eventlog.py +12 -2
  57. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_hookadapter.py +620 -14
  58. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_layers.py +2 -0
  59. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_mcpserver.py +54 -2
  60. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_memory.py +339 -32
  61. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_memory_compact_tool.py +2 -1
  62. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_memory_component.py +131 -26
  63. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_memory_dream.py +36 -0
  64. bantamkit-0.37.0/tests/test_memory_native.py +210 -0
  65. bantamkit-0.37.0/tests/test_memory_queries.py +566 -0
  66. bantamkit-0.37.0/tests/test_memory_retrieval.py +263 -0
  67. bantamkit-0.37.0/tests/test_memory_skills.py +273 -0
  68. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_memory_strings.py +73 -1
  69. bantamkit-0.37.0/tests/test_memory_usage.py +291 -0
  70. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_served_tool_count_records.py +11 -11
  71. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_skillaudit.py +1 -1
  72. bantamkit-0.37.0/tests/test_skillaudit_roots.py +111 -0
  73. bantamkit-0.37.0/tests/test_skilldraft.py +444 -0
  74. bantamkit-0.37.0/tests/test_skillfile.py +488 -0
  75. bantamkit-0.37.0/tests/test_skillhost.py +246 -0
  76. bantamkit-0.37.0/tests/test_skillimprove.py +429 -0
  77. bantamkit-0.37.0/tests/test_skillimprove_signals.py +558 -0
  78. bantamkit-0.37.0/tests/test_skillinstall.py +334 -0
  79. bantamkit-0.37.0/tests/test_skillmine.py +1014 -0
  80. bantamkit-0.37.0/tests/test_skillmine_daily.py +418 -0
  81. bantamkit-0.37.0/tests/test_skillpromote.py +269 -0
  82. bantamkit-0.37.0/tests/test_skillpropose.py +356 -0
  83. bantamkit-0.37.0/tests/test_skillreport.py +479 -0
  84. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_status_surface.py +145 -5
  85. bantamkit-0.37.0/tests/test_storage_bar.py +42 -0
  86. bantamkit-0.37.0/tests/test_storage_coldindex.py +174 -0
  87. bantamkit-0.37.0/tests/test_storage_hotindex.py +302 -0
  88. bantamkit-0.37.0/tests/test_storage_log.py +348 -0
  89. bantamkit-0.37.0/tests/test_storage_log_consumers.py +187 -0
  90. bantamkit-0.37.0/tests/test_storage_recall_index.py +182 -0
  91. bantamkit-0.37.0/tests/test_storage_retention.py +499 -0
  92. bantamkit-0.37.0/tests/test_storage_tiers.py +186 -0
  93. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_tokenledger.py +1 -0
  94. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_tool_annotations.py +2 -2
  95. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_tool_manifest.py +23 -0
  96. bantamkit-0.37.0/tests/test_touch_bashturn.py +79 -0
  97. bantamkit-0.37.0/tests/test_touch_context.py +104 -0
  98. bantamkit-0.37.0/tests/test_touch_graph.py +235 -0
  99. bantamkit-0.37.0/tests/test_touch_log.py +517 -0
  100. bantamkit-0.37.0/tests/test_touch_recall_file.py +187 -0
  101. bantamkit-0.37.0/tests/test_touch_refs.py +152 -0
  102. bantamkit-0.37.0/tests/test_touch_summary.py +262 -0
  103. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_unknown_arguments.py +2 -2
  104. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_version_agreement.py +99 -2
  105. {bantamkit-0.36.2 → bantamkit-0.37.0}/.gitignore +0 -0
  106. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/contracts/default.yaml +0 -0
  107. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/manifest.yaml +0 -0
  108. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/HISTORY.md +0 -0
  109. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/README.md +0 -0
  110. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/docs/architecture.md +0 -0
  111. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/docs/runbook.md +0 -0
  112. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/issues/142-settlement-timeout.md +0 -0
  113. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/patches/0009-retry-budget.patch +0 -0
  114. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/src/ledger/__init__.py +0 -0
  115. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/src/ledger/config.py +0 -0
  116. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/src/ledger/errors.py +0 -0
  117. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/src/ledger/posting.py +0 -0
  118. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/src/ledger/registry.py +0 -0
  119. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/src/ledger/report.py +0 -0
  120. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/src/ledger/retry.py +0 -0
  121. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/src/ledger/settle.py +0 -0
  122. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/src/ledger/validate.py +0 -0
  123. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/tests/test_posting.py +0 -0
  124. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/repo/tests/test_settle.py +0 -0
  125. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/tasks/dt-error-contract.yaml +0 -0
  126. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/tasks/dt-handler-map.yaml +0 -0
  127. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/tasks/dt-patch-before-after.yaml +0 -0
  128. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/tasks/dt-retry-attempts.yaml +0 -0
  129. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/tasks/dt-settlement-config.yaml +0 -0
  130. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/tasks/dt-symbol-home.yaml +0 -0
  131. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/tasks/dt-trace-blame.yaml +0 -0
  132. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/devteam/tasks/dt-unread-key.yaml +0 -0
  133. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/document/tasks/doc-large-in-137.yaml +0 -0
  134. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/document/tasks/doc-large-in-359.yaml +0 -0
  135. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/document/tasks/doc-large-in-372.yaml +0 -0
  136. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/document/tasks/doc-large-out-11764.yaml +0 -0
  137. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/document/tasks/doc-large-out-4137.yaml +0 -0
  138. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/document/tasks/doc-large-out-8022.yaml +0 -0
  139. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/document/tasks/doc-small-137.yaml +0 -0
  140. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/document/tasks/doc-small-261.yaml +0 -0
  141. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/document/tasks/doc-small-388.yaml +0 -0
  142. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/fixtures/.gitkeep +0 -0
  143. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/fixtures/catalog.json +0 -0
  144. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/perturbations/task-completion.yaml +0 -0
  145. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/.gitkeep +0 -0
  146. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/extract-contact.yaml +0 -0
  147. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/extract-invoice.yaml +0 -0
  148. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/extract-order.yaml +0 -0
  149. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/extract-schedule.yaml +0 -0
  150. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/extract-versions.yaml +0 -0
  151. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/nav-prod-port.yaml +0 -0
  152. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/nav-release-bundle.yaml +0 -0
  153. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/recall-audit-retention.yaml +0 -0
  154. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/recall-cache-ttl.yaml +0 -0
  155. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/recall-db-port.yaml +0 -0
  156. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/recall-deploy.yaml +0 -0
  157. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/recall-env-endpoint.yaml +0 -0
  158. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/recall-oncall-rotation.yaml +0 -0
  159. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/recall-oncall.yaml +0 -0
  160. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/recall-org-quota.yaml +0 -0
  161. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/recall-owner.yaml +0 -0
  162. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/shop-basket-total.yaml +0 -0
  163. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/shop-cheapest.yaml +0 -0
  164. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/shop-compare.yaml +0 -0
  165. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/shop-gadget-value.yaml +0 -0
  166. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/shop-stock-total.yaml +0 -0
  167. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/evals/tasks/shop-total.yaml +0 -0
  168. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/pricing/default.json +0 -0
  169. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/profiles/default.yaml +0 -0
  170. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/profiles/patient.yaml +0 -0
  171. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/rubrics/.gitkeep +0 -0
  172. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/rubrics/code-quality.yaml +0 -0
  173. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/rubrics/grounded-completion.yaml +0 -0
  174. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/rubrics/task-completion.yaml +0 -0
  175. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/schemas/shiftwork-checkpoint.json +0 -0
  176. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/skills/.gitkeep +0 -0
  177. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/skills/file-graph.md +0 -0
  178. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/.gitkeep +0 -0
  179. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/bantamkit_read.json +0 -0
  180. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/bantamkit_status.json +0 -0
  181. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/build_identity.json +0 -0
  182. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/document_list.json +0 -0
  183. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/document_read.json +0 -0
  184. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/file_graph.json +0 -0
  185. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/memory_dream.json +0 -0
  186. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/repo_map.json +0 -0
  187. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/shiftwork_clock_in.json +0 -0
  188. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/shiftwork_clock_out.json +0 -0
  189. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/shiftwork_plan.json +0 -0
  190. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/skill_audit.json +0 -0
  191. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/token_ledger.json +0 -0
  192. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/validate_json.json +0 -0
  193. {bantamkit-0.36.2 → bantamkit-0.37.0}/_assets/tools/work_plan.json +0 -0
  194. {bantamkit-0.36.2 → bantamkit-0.37.0}/hatch_build.py +0 -0
  195. {bantamkit-0.36.2 → bantamkit-0.37.0}/pyproject.toml +0 -0
  196. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/agent.py +0 -0
  197. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/assets.py +0 -0
  198. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/budget.py +0 -0
  199. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/client.py +0 -0
  200. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/contract.py +0 -0
  201. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/criticreplay.py +0 -0
  202. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/critique.py +0 -0
  203. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/docmanifest.py +0 -0
  204. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/docread.py +0 -0
  205. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/evalrun.py +0 -0
  206. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/filegraph.py +0 -0
  207. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/loopguard.py +0 -0
  208. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/mcpreport.py +0 -0
  209. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/mcpstdio.py +0 -0
  210. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/memory/__init__.py +0 -0
  211. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/memory/layers.py +0 -0
  212. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/pdfread.py +0 -0
  213. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/pricing.py +0 -0
  214. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/profile.py +0 -0
  215. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/repomap.py +0 -0
  216. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/selfupdate.py +0 -0
  217. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/statusline.py +0 -0
  218. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/structured.py +0 -0
  219. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/textutil.py +0 -0
  220. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/tokenledger.py +0 -0
  221. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/updatecheck.py +0 -0
  222. {bantamkit-0.36.2 → bantamkit-0.37.0}/src/bantamkit/workplan.py +0 -0
  223. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/cli_exit_status_probe.py +0 -0
  224. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/bad-crc.docx +0 -0
  225. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/charref-4301-digits.html +0 -0
  226. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/charset-table.json +0 -0
  227. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/compression-method-9.docx +0 -0
  228. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/corrupt-deflate.docx +0 -0
  229. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/encrypted-member.docx +0 -0
  230. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/encrypted-mimetype.odt +0 -0
  231. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/eszett-cell-ref.xlsx +0 -0
  232. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/internal-dtd-entity.docx +0 -0
  233. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/rfc2231-charset.eml +0 -0
  234. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/rfc822-nested-twice.eml +0 -0
  235. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/unicode-digit-shared-string.xlsx +0 -0
  236. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/docread/x-uuencode.eml +0 -0
  237. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/f8404ab-perturbation-baseline.json +0 -0
  238. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/data/platform-assumption-baseline.json +0 -0
  239. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/docread_fixtures.py +0 -0
  240. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/perturbation_baseline_harness.py +0 -0
  241. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/rbp16_effect_probe.py +0 -0
  242. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/rbp18_payload_probe.py +0 -0
  243. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_adapter.py +0 -0
  244. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_agent.py +0 -0
  245. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_amendguard.py +0 -0
  246. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_assets.py +0 -0
  247. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_bantamkit_gitignore.py +0 -0
  248. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_bantamkit_read_tool.py +0 -0
  249. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_budget.py +0 -0
  250. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_cli_oneshot.py +0 -0
  251. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_client.py +0 -0
  252. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_compaction_corpus_survey.py +0 -0
  253. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_conformance.py +0 -0
  254. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_conformance_harness_resilience.py +0 -0
  255. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_contract_fanout.py +0 -0
  256. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_contract_patterns.py +0 -0
  257. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_contract_refs.py +0 -0
  258. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_criticreplay.py +0 -0
  259. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_critique.py +0 -0
  260. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_doc_commands_gate.py +0 -0
  261. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_docread.py +0 -0
  262. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_document_manifest_parity.py +0 -0
  263. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_document_setup.py +0 -0
  264. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_document_tasks.py +0 -0
  265. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_document_tools.py +0 -0
  266. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_encoding_gate.py +0 -0
  267. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_evalrun.py +0 -0
  268. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_field_program_gates.py +0 -0
  269. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_field_programs.py +0 -0
  270. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_filegraph.py +0 -0
  271. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_hostinstall.py +0 -0
  272. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_hostinstall_hooks.py +0 -0
  273. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_install_shape.py +0 -0
  274. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_ladder_statistics.py +0 -0
  275. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_launcher_which.py +0 -0
  276. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_loopguard.py +0 -0
  277. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_mcp_endpoint.py +0 -0
  278. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_mcp_request_guard.py +0 -0
  279. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_mcpdrift.py +0 -0
  280. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_mcpreport.py +0 -0
  281. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_mcpstdio_frames.py +0 -0
  282. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_memory_divergence.py +0 -0
  283. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_memory_layers.py +0 -0
  284. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_memory_lifecycle.py +0 -0
  285. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_memory_store_tripwire.py +0 -0
  286. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_mutmatrix.py +0 -0
  287. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_nativeexport.py +0 -0
  288. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_newline_gate.py +0 -0
  289. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_packaging.py +0 -0
  290. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_pdfread.py +0 -0
  291. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_pinharness_ledger.py +0 -0
  292. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_platform_assumption_gate.py +0 -0
  293. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_pricing.py +0 -0
  294. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_readme_separation.py +0 -0
  295. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_repo_map_tool.py +0 -0
  296. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_repomap.py +0 -0
  297. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_selfupdate.py +0 -0
  298. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_shiftwork.py +0 -0
  299. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_statusline.py +0 -0
  300. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_structured.py +0 -0
  301. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_thread_exception_gate.py +0 -0
  302. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_updatecheck.py +0 -0
  303. {bantamkit-0.36.2 → bantamkit-0.37.0}/tests/test_workplan.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.5
1
+ Metadata-Version: 2.4
2
2
  Name: bantamkit
3
- Version: 0.36.2
3
+ Version: 0.37.0
4
4
  Summary: Persistent memory for coding agents: an MCP server for Claude Code, Claude Desktop, Cursor and VS Code Copilot, plus a Python library that lifts small-model agents. Install once, run offline.
5
5
  Project-URL: Homepage, https://github.com/Ink01101011/bantamkit
6
6
  Project-URL: Repository, https://github.com/Ink01101011/bantamkit
@@ -74,13 +74,12 @@ Then restart the host (in Claude Code, open a new session) and ask the agent to
74
74
  - **Offline after one install.** `--install` records the venv's console script by absolute path,
75
75
  so no launch needs the network or your shell's PATH.
76
76
  - **Claude Code hooks, if you want them.** `--install-hooks` puts the memory index in front of
77
- each new session, surfaces matching facts on each prompt, mirrors each fact Claude Code writes
78
- into its own auto-memory into the project store (one way, new writes only), and nudges a save at
79
- the end of a long session that saved nothing
77
+ each new session, surfaces matching facts on each prompt, and nudges a save at the end of a
78
+ long session that saved nothing
80
79
  ([docs/hooks.md](https://github.com/Ink01101011/bantamkit/blob/main/docs/hooks.md)).
81
80
  - **More than memory.** JSON Schema validation, a token ledger read off the host's transcripts,
82
81
  a skill-catalogue audit, and shift-work tools that plan and hand off multi-step jobs —
83
- [the fourteen tools](#-what-it-serves).
82
+ [the fifteen tools](#-what-it-serves).
84
83
  - **Same answers as the Node server.** The two share a memory store on disk, and every surface
85
84
  is compared between both runtimes by a conformance suite (`node tools/conformance/run.mjs
86
85
  --all` in the repository), so install whichever your host makes easy.
@@ -103,10 +102,10 @@ Then restart the host (in Claude Code, open a new session) and ask the agent to
103
102
  | [Configuration](#-configuration) | Every flag and variable, with its default |
104
103
  | [Update](#-update) | `--update`, pipx, uv, then restart |
105
104
  | [Troubleshooting](#-troubleshooting) | Timeouts, refusals, the wrong store |
106
- | [What it serves](#-what-it-serves) | 14 tools, one prompt, two resource templates |
105
+ | [What it serves](#-what-it-serves) | 15 tools, three prompts, two resource templates |
107
106
  | [Requirements](#-requirements) | Python and dependencies |
108
107
  | [The asset pack](#-the-asset-pack) | `--assets-root`, `BANTAMKIT_ASSETS` |
109
- | [The operator CLI: `python -m bantamkit.memory`](#-the-operator-cli-python--m-bantamkitmemory) | status, lint, compact, archived, archive, restore, list, candidates, merge |
108
+ | [The operator CLI: `python -m bantamkit.memory`](#-the-operator-cli-python--m-bantamkitmemory) | status, lint, compact, archived, archive, restore |
110
109
  | [Where the Python and Node servers differ](#-where-the-python-and-node-servers-differ) | One store; pdf/.doc/.rtf, CLI name, `build_id`, YAML only PyYAML reads |
111
110
  | [Module API](#-module-api) | `import bantamkit`: the library half, measured from the wheel |
112
111
  | [Development](#-development) | Clone, test, lint, conformance |
@@ -145,9 +144,9 @@ CPU architecture and Python minor version** (some wheels, such as `pydantic_core
145
144
  one platform only), copy `wheels/` across, and install from it:
146
145
 
147
146
  ```bash
148
- python -m pip download "bantamkit[mcp]==0.36.2" -d wheels
147
+ python -m pip download "bantamkit[mcp]==0.37.0" -d wheels
149
148
  python -m venv <env>
150
- <env>/bin/pip install --no-index --find-links wheels "bantamkit[mcp]==0.36.2"
149
+ <env>/bin/pip install --no-index --find-links wheels "bantamkit[mcp]==0.37.0"
151
150
  <env>/bin/bantamkit-mcp --install cursor
152
151
  ```
153
152
 
@@ -279,6 +278,7 @@ Flags go in the entry's `args`; environment variables in its `env` block (or
279
278
  | `--k K` | Default recall budget | `3` | `"--k", "5"` |
280
279
  | `--index-budget BYTES` | Memory index byte budget | `24000` | `"--index-budget", "32000"` |
281
280
  | `BANTAMKIT_EVENT_LOG` | Logs tool outcomes as JSONL | off; `on` → `<store>/events/mcp.jsonl`; other values are a path | `"env": {"BANTAMKIT_EVENT_LOG": "on"}` |
281
+ | `BANTAMKIT_SKILL_AUTO` | Skills from experience (#206): lets the daily run install a skill it mined, make low-risk edits to installed skills and promote a much-used one to a native link on its own. Off, the same work waits for you as proposals in the `skill_propose` prompt | **off** in 0.37.0; `on` (or `1`/`true`/`yes`) opts in | `"env": {"BANTAMKIT_SKILL_AUTO": "on"}` |
282
282
  | `BANTAMKIT_ASSETS` | Your own asset pack (skills, rubrics, schemas) | the pack inside the package | `"env": {"BANTAMKIT_ASSETS": "/abs/my-assets"}` |
283
283
  | `BANTAMKIT_HOST_LOG_ROOT` | Where `--mcp-report` finds the host's MCP logs | macOS `~/Library/Caches/claude-cli-nodejs`; elsewhere unset | `BANTAMKIT_HOST_LOG_ROOT=/abs/logs bantamkit-mcp --mcp-report` |
284
284
  | `BANTAMKIT_PRICES` | Price table for the token ledger | `pricing/default.json` in the asset pack | `"env": {"BANTAMKIT_PRICES": "/abs/prices.json"}` |
@@ -328,7 +328,7 @@ you**; a new version with an old `build_id` means an old process.
328
328
 
329
329
  ## 🧰 What it serves
330
330
 
331
- It serves 14 tools, the `bantamkit_status` prompt and two resource templates
331
+ It serves 15 tools, three prompts (`bantamkit_status`, `skill_audit` and `skill_propose`) and two resource templates
332
332
  (`bantamkit://skills/{name}`, `bantamkit://rubrics/{name}`):
333
333
 
334
334
  | Tool | What it does |
@@ -337,6 +337,7 @@ It serves 14 tools, the `bantamkit_status` prompt and two resource templates
337
337
  | `memory_recall` | retrieve facts matching a query |
338
338
  | `memory_compact` | archive the stalest facts to fit the index budget |
339
339
  | `memory_dream` | consolidate facts the project and profile layers hold under the same name |
340
+ | `memory_queries` | list the facts that have no likely-prompt queries yet, and store the queries written for them; recall matches a prompt against them |
340
341
  | `validate_json` | validate a document against a JSON Schema |
341
342
  | `skill_audit` | audit a skill catalogue for findings |
342
343
  | `shiftwork_clock_in` | open a unit of work and get its brief |
@@ -374,13 +375,9 @@ python -m bantamkit.memory compact # archive the stalest facts
374
375
  python -m bantamkit.memory archived # list what compaction has moved out
375
376
  python -m bantamkit.memory archive <name>
376
377
  python -m bantamkit.memory restore <name>
377
- python -m bantamkit.memory list [--type T] [--outcome error|success] [--status active|done]
378
- python -m bantamkit.memory candidates [--older-than DAYS] [--apply]
379
- python -m bantamkit.memory merge --names A B --name NEW --type T --description D --body TEXT [--apply]
380
378
  ```
381
379
 
382
- `archive` moves a fact out without deleting it; `restore` brings it back by name. `candidates`
383
- and `merge` are dry runs unless `--apply` is given.
380
+ `archive` moves a fact out without deleting it; `restore` brings it back by name.
384
381
  Full reference: [docs/memory.md → The operator CLI](https://github.com/Ink01101011/bantamkit/blob/main/docs/memory.md#the-operator-cli).
385
382
 
386
383
  ## 🔀 Where the Python and Node servers differ
@@ -438,7 +435,7 @@ as a side effect of the package's own imports (`agent`, `assets`, `budget`, `cli
438
435
  | `bantamkit.memory` | the memory store | `Memory`, `MemoryStore` |
439
436
  | **9 modules** | | **30 values, no `__all__`** |
440
437
 
441
- **This is not the npm package's export surface.** Both runtimes serve the same fourteen MCP
438
+ **This is not the npm package's export surface.** Both runtimes serve the same fifteen MCP
442
439
  tools, but what each one exports *to an importer* is a different product: here it is the
443
440
  agent/critique/eval library above; there it is the memory store, the asset pack, the event log,
444
441
  the shift-work tools and a set of CPython-semantics shims — 141 values behind one entry point. Of
@@ -43,13 +43,12 @@ Then restart the host (in Claude Code, open a new session) and ask the agent to
43
43
  - **Offline after one install.** `--install` records the venv's console script by absolute path,
44
44
  so no launch needs the network or your shell's PATH.
45
45
  - **Claude Code hooks, if you want them.** `--install-hooks` puts the memory index in front of
46
- each new session, surfaces matching facts on each prompt, mirrors each fact Claude Code writes
47
- into its own auto-memory into the project store (one way, new writes only), and nudges a save at
48
- the end of a long session that saved nothing
46
+ each new session, surfaces matching facts on each prompt, and nudges a save at the end of a
47
+ long session that saved nothing
49
48
  ([docs/hooks.md](https://github.com/Ink01101011/bantamkit/blob/main/docs/hooks.md)).
50
49
  - **More than memory.** JSON Schema validation, a token ledger read off the host's transcripts,
51
50
  a skill-catalogue audit, and shift-work tools that plan and hand off multi-step jobs —
52
- [the fourteen tools](#-what-it-serves).
51
+ [the fifteen tools](#-what-it-serves).
53
52
  - **Same answers as the Node server.** The two share a memory store on disk, and every surface
54
53
  is compared between both runtimes by a conformance suite (`node tools/conformance/run.mjs
55
54
  --all` in the repository), so install whichever your host makes easy.
@@ -72,10 +71,10 @@ Then restart the host (in Claude Code, open a new session) and ask the agent to
72
71
  | [Configuration](#-configuration) | Every flag and variable, with its default |
73
72
  | [Update](#-update) | `--update`, pipx, uv, then restart |
74
73
  | [Troubleshooting](#-troubleshooting) | Timeouts, refusals, the wrong store |
75
- | [What it serves](#-what-it-serves) | 14 tools, one prompt, two resource templates |
74
+ | [What it serves](#-what-it-serves) | 15 tools, three prompts, two resource templates |
76
75
  | [Requirements](#-requirements) | Python and dependencies |
77
76
  | [The asset pack](#-the-asset-pack) | `--assets-root`, `BANTAMKIT_ASSETS` |
78
- | [The operator CLI: `python -m bantamkit.memory`](#-the-operator-cli-python--m-bantamkitmemory) | status, lint, compact, archived, archive, restore, list, candidates, merge |
77
+ | [The operator CLI: `python -m bantamkit.memory`](#-the-operator-cli-python--m-bantamkitmemory) | status, lint, compact, archived, archive, restore |
79
78
  | [Where the Python and Node servers differ](#-where-the-python-and-node-servers-differ) | One store; pdf/.doc/.rtf, CLI name, `build_id`, YAML only PyYAML reads |
80
79
  | [Module API](#-module-api) | `import bantamkit`: the library half, measured from the wheel |
81
80
  | [Development](#-development) | Clone, test, lint, conformance |
@@ -114,9 +113,9 @@ CPU architecture and Python minor version** (some wheels, such as `pydantic_core
114
113
  one platform only), copy `wheels/` across, and install from it:
115
114
 
116
115
  ```bash
117
- python -m pip download "bantamkit[mcp]==0.36.2" -d wheels
116
+ python -m pip download "bantamkit[mcp]==0.37.0" -d wheels
118
117
  python -m venv <env>
119
- <env>/bin/pip install --no-index --find-links wheels "bantamkit[mcp]==0.36.2"
118
+ <env>/bin/pip install --no-index --find-links wheels "bantamkit[mcp]==0.37.0"
120
119
  <env>/bin/bantamkit-mcp --install cursor
121
120
  ```
122
121
 
@@ -248,6 +247,7 @@ Flags go in the entry's `args`; environment variables in its `env` block (or
248
247
  | `--k K` | Default recall budget | `3` | `"--k", "5"` |
249
248
  | `--index-budget BYTES` | Memory index byte budget | `24000` | `"--index-budget", "32000"` |
250
249
  | `BANTAMKIT_EVENT_LOG` | Logs tool outcomes as JSONL | off; `on` → `<store>/events/mcp.jsonl`; other values are a path | `"env": {"BANTAMKIT_EVENT_LOG": "on"}` |
250
+ | `BANTAMKIT_SKILL_AUTO` | Skills from experience (#206): lets the daily run install a skill it mined, make low-risk edits to installed skills and promote a much-used one to a native link on its own. Off, the same work waits for you as proposals in the `skill_propose` prompt | **off** in 0.37.0; `on` (or `1`/`true`/`yes`) opts in | `"env": {"BANTAMKIT_SKILL_AUTO": "on"}` |
251
251
  | `BANTAMKIT_ASSETS` | Your own asset pack (skills, rubrics, schemas) | the pack inside the package | `"env": {"BANTAMKIT_ASSETS": "/abs/my-assets"}` |
252
252
  | `BANTAMKIT_HOST_LOG_ROOT` | Where `--mcp-report` finds the host's MCP logs | macOS `~/Library/Caches/claude-cli-nodejs`; elsewhere unset | `BANTAMKIT_HOST_LOG_ROOT=/abs/logs bantamkit-mcp --mcp-report` |
253
253
  | `BANTAMKIT_PRICES` | Price table for the token ledger | `pricing/default.json` in the asset pack | `"env": {"BANTAMKIT_PRICES": "/abs/prices.json"}` |
@@ -297,7 +297,7 @@ you**; a new version with an old `build_id` means an old process.
297
297
 
298
298
  ## 🧰 What it serves
299
299
 
300
- It serves 14 tools, the `bantamkit_status` prompt and two resource templates
300
+ It serves 15 tools, three prompts (`bantamkit_status`, `skill_audit` and `skill_propose`) and two resource templates
301
301
  (`bantamkit://skills/{name}`, `bantamkit://rubrics/{name}`):
302
302
 
303
303
  | Tool | What it does |
@@ -306,6 +306,7 @@ It serves 14 tools, the `bantamkit_status` prompt and two resource templates
306
306
  | `memory_recall` | retrieve facts matching a query |
307
307
  | `memory_compact` | archive the stalest facts to fit the index budget |
308
308
  | `memory_dream` | consolidate facts the project and profile layers hold under the same name |
309
+ | `memory_queries` | list the facts that have no likely-prompt queries yet, and store the queries written for them; recall matches a prompt against them |
309
310
  | `validate_json` | validate a document against a JSON Schema |
310
311
  | `skill_audit` | audit a skill catalogue for findings |
311
312
  | `shiftwork_clock_in` | open a unit of work and get its brief |
@@ -343,13 +344,9 @@ python -m bantamkit.memory compact # archive the stalest facts
343
344
  python -m bantamkit.memory archived # list what compaction has moved out
344
345
  python -m bantamkit.memory archive <name>
345
346
  python -m bantamkit.memory restore <name>
346
- python -m bantamkit.memory list [--type T] [--outcome error|success] [--status active|done]
347
- python -m bantamkit.memory candidates [--older-than DAYS] [--apply]
348
- python -m bantamkit.memory merge --names A B --name NEW --type T --description D --body TEXT [--apply]
349
347
  ```
350
348
 
351
- `archive` moves a fact out without deleting it; `restore` brings it back by name. `candidates`
352
- and `merge` are dry runs unless `--apply` is given.
349
+ `archive` moves a fact out without deleting it; `restore` brings it back by name.
353
350
  Full reference: [docs/memory.md → The operator CLI](https://github.com/Ink01101011/bantamkit/blob/main/docs/memory.md#the-operator-cli).
354
351
 
355
352
  ## 🔀 Where the Python and Node servers differ
@@ -407,7 +404,7 @@ as a side effect of the package's own imports (`agent`, `assets`, `budget`, `cli
407
404
  | `bantamkit.memory` | the memory store | `Memory`, `MemoryStore` |
408
405
  | **9 modules** | | **30 values, no `__all__`** |
409
406
 
410
- **This is not the npm package's export surface.** Both runtimes serve the same fourteen MCP
407
+ **This is not the npm package's export surface.** Both runtimes serve the same fifteen MCP
411
408
  tools, but what each one exports *to an importer* is a different product: here it is the
412
409
  agent/critique/eval library above; there it is the memory store, the asset pack, the event log,
413
410
  the shift-work tools and a set of CPython-semantics shims — 141 values behind one entry point. Of
@@ -0,0 +1,12 @@
1
+ # Likely-prompt queries
2
+
3
+ For each fact, write the prompts a user would type to a coding assistant when this fact is what they need.
4
+
5
+ - Three in the user's own language and three in English (`queries` holds all six, the user's language first).
6
+ - Short: 5 to 25 words. Vary them: one direct question, one task request, one terse follow-up.
7
+ - Keep technical terms in English where the user would: commands, file names, product names, error codes.
8
+ - Use only what the fact says. Do not invent facts, do not just restate the fact's name, and never copy more than
9
+ five words of the body verbatim.
10
+
11
+ Store them with `memory_queries` (`{"facts": [{"name": ..., "layer": ..., "queries": [...]}]}`), or pass
12
+ `queries` to `memory_save` when you save the fact.
@@ -23,6 +23,13 @@ past-you would have used. Do this before acting, not after.
23
23
 
24
24
  Write it to match the future recall QUERY, not to summarize the body.
25
25
  Ask: "what words will future-me search with?" Put related memory names in links.
26
+ Fill keywords with the words the user will actually type, in their language — recall matches those too.
27
+
28
+ ## Likely-prompt queries
29
+
30
+ When you save, also pass `queries`: three prompts in the user's language and three in English that a user would
31
+ type when this fact is what they need. Short and varied, technical terms kept in English, never more than five
32
+ words copied from the body. When `memory_queries` lists facts without queries, write theirs.
26
33
 
27
34
  ## On "duplicate" replies
28
35
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "memory_compact",
3
3
  "title": "Compact the memory store",
4
- "description": "Free room in persistent memory when `memory_save` was refused for budget. Archives the stalest facts of the writable project store until a fact as large as the biggest one kept will fit, and returns what moved — every archived name with its type and description. Nothing is deleted: archived facts leave the index but stay on disk under archive/, and bringing one back is an operator action rather than a tool — `bantamkit-memory restore <name>` (Node) or `python -m bantamkit.memory restore <name>` (Python) on the store; no tool deletes a fact. Read-only grants and the profile layer are never touched. Call it after a budget refusal, then retry the save; calling it under budget archives nothing and says so. It is not the pass for two copies of one name across layers — that is memory_dream.",
4
+ "description": "Free room in persistent memory when `memory_save` was refused for budget. Archives the stalest facts of the writable project store until a fact as large as the biggest one kept will fit, and returns what moved — every archived name with its type and description. Nothing is deleted: archived facts leave the index but stay on disk under archive/, memory_recall with `include_archived` still finds them, and bringing one back is an operator action rather than a tool — `bantamkit-memory restore <name>` (Node) or `python -m bantamkit.memory restore <name>` (Python) on the store; no tool deletes a fact. Read-only grants and the profile layer are never touched. Call it after a budget refusal, then retry the save; calling it under budget archives nothing and says so. It is not the pass for two copies of one name across layers — that is memory_dream.",
5
5
  "surfaces": [
6
6
  "agent",
7
7
  "mcp"
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "memory_queries",
3
+ "title": "Likely-prompt queries for saved facts",
4
+ "description": "Write, or list the facts that still lack, the likely-prompt queries recall matches a user's prompt against — for each fact, the prompts a user would type when that fact is what they need. Call it with {} at the end of a session that saved facts, or when bantamkit_status reports `queries: n of m facts` with n below m: it answers up to 10 facts with no queries yet (layer, name, description, a body excerpt), the writing instructions, and `remaining`. Then call it with {\"facts\": [{name, layer?, queries}]} to store what you wrote. Every item is checked before anything is written and the first bad one refuses the whole call — an unknown name or layer, more than 8 queries, one over 200 characters; `queries: []` removes a fact's entry. No fact file changes: queries live in a per-layer sidecar under ~/.bantamkit/queries/, keyed to the fact's content, so a fact edited later is listed as missing again. memory_save takes `queries` directly for a fact you are saving now; this tool is for facts already on disk.",
5
+ "surfaces": [
6
+ "mcp"
7
+ ],
8
+ "parameters": {
9
+ "type": "object",
10
+ "properties": {
11
+ "facts": {
12
+ "anyOf": [
13
+ {
14
+ "type": "array",
15
+ "items": {
16
+ "type": "object",
17
+ "properties": {
18
+ "name": {
19
+ "type": "string",
20
+ "description": "The fact's exact name (its slug)."
21
+ },
22
+ "layer": {
23
+ "type": "string",
24
+ "description": "project, profile, extra:<name> or native; optional: the first layer holding the name"
25
+ },
26
+ "queries": {
27
+ "type": "array",
28
+ "items": {
29
+ "type": "string"
30
+ },
31
+ "description": "Up to 8 prompts, each at most 200 characters, in the user's language and in English; [] removes the fact's entry."
32
+ }
33
+ },
34
+ "required": [
35
+ "name",
36
+ "queries"
37
+ ]
38
+ }
39
+ },
40
+ {
41
+ "type": "null"
42
+ }
43
+ ],
44
+ "description": "Omit to list the facts missing queries"
45
+ }
46
+ },
47
+ "title": "memory_queriesArguments",
48
+ "additionalProperties": false
49
+ },
50
+ "output_schema": {
51
+ "type": "object",
52
+ "properties": {
53
+ "result": {
54
+ "type": "string",
55
+ "description": "`missing` for the list call, `written` for the store call, `error` with `reason` when refused."
56
+ },
57
+ "facts": {
58
+ "type": "array",
59
+ "items": {
60
+ "type": "object"
61
+ },
62
+ "description": "With `missing`: up to 10 {layer, name, description, body} still without queries."
63
+ },
64
+ "remaining": {
65
+ "type": "integer",
66
+ "description": "How many facts across the readable layers still have no queries after this call."
67
+ },
68
+ "instructions": {
69
+ "type": "string",
70
+ "description": "With `missing`: how to write good queries."
71
+ },
72
+ "written": {
73
+ "type": "integer",
74
+ "description": "With `written`: how many items were stored."
75
+ },
76
+ "reason": {
77
+ "type": "string",
78
+ "description": "With result `error`: one sentence saying why the call was refused."
79
+ }
80
+ },
81
+ "required": [
82
+ "result"
83
+ ],
84
+ "additionalProperties": true,
85
+ "title": "memory_queriesDictOutput"
86
+ },
87
+ "annotations": {
88
+ "readOnlyHint": false,
89
+ "destructiveHint": false,
90
+ "openWorldHint": false
91
+ }
92
+ }
@@ -1,16 +1,14 @@
1
1
  {
2
2
  "name": "memory_recall",
3
3
  "title": "Recall memories",
4
- "description": "Search persistent memory for facts a past session saved. Call it BEFORE starting a task that resembles past work, and when the user refers to something decided earlier; use memory_save to add a fact, and memory_compact or memory_dream only to tidy the store — this tool never changes what a fact says. Reads every layer in order — the project store, any read-only grants in .bantamkit/config.yaml, then the machine-wide profile — and returns the top word matches, never fewer than the store default of 3 when that many match; a query that is exactly a fact's name returns that fact alone. Why it is not read-only: every hit is appended to the usage ledger (~/.bantamkit/usage/<store-id>.jsonl) as a recall event — the staleness order memory_compact archives by — and a project fact file still in the 0.35.x format is rewritten once into the current one; both are best-effort and never fail a recall. A fact file that cannot be read is named in the reply, never silently skipped. Pass outcome: error to see only recorded failures.",
4
+ "description": "Search persistent memory for facts a past session saved. Call it BEFORE starting a task that resembles past work, and when the user refers to something decided earlier; use memory_save to add a fact, and memory_compact or memory_dream only to tidy the store — this tool never changes what a fact says. Reads every layer in order — the project store, any read-only grants in .bantamkit/config.yaml, then the machine-wide profile — and returns the top word matches, never fewer than the store default of 3 when that many match; a query that is exactly a fact's name returns that fact alone. Pass `file` instead of `query` to see the facts linked to a file. Why it is not read-only: every hit is appended to the usage ledger (~/.bantamkit/usage/<store-id>.jsonl) as a recall event — the staleness order memory_compact archives by — and a project fact file still in the 0.35.x format is rewritten once into the current one; both are best-effort and never fail a recall. A fact file that cannot be read is named in the reply, never silently skipped. Pass outcome: error to see only recorded failures.",
5
5
  "surfaces": [
6
6
  "agent",
7
7
  "mcp"
8
8
  ],
9
9
  "parameters": {
10
10
  "type": "object",
11
- "required": [
12
- "query"
13
- ],
11
+ "required": [],
14
12
  "properties": {
15
13
  "query": {
16
14
  "type": "string",
@@ -20,6 +18,15 @@
20
18
  "type": "integer",
21
19
  "description": "Facts wanted, clamped to 1..5. Raised to the store default of 3 when smaller; never lowered below it."
22
20
  },
21
+ "include_archived": {
22
+ "type": "boolean",
23
+ "default": false,
24
+ "description": "Also search facts compaction moved to archive/. Archived matches come after the live ones, tagged [archived]."
25
+ },
26
+ "file": {
27
+ "type": "string",
28
+ "description": "A tracked file, or the shortest unique suffix of one (store.ts, memory/store.ts). Returns the facts linked to it and when it was last touched; query is then ignored."
29
+ },
23
30
  "outcome": {
24
31
  "type": "string",
25
32
  "enum": [
@@ -45,6 +45,20 @@
45
45
  },
46
46
  "description": "names of related memories"
47
47
  },
48
+ "keywords": {
49
+ "type": "array",
50
+ "items": {
51
+ "type": "string"
52
+ },
53
+ "description": "Words the user will type when they need this fact, in the user's own language as well as English (e.g. Thai and English terms)"
54
+ },
55
+ "queries": {
56
+ "type": "array",
57
+ "items": {
58
+ "type": "string"
59
+ },
60
+ "description": "The prompts a user would type when this fact is what they need: three in the user's language and three in English, at most 8, each at most 200 characters"
61
+ },
48
62
  "outcome": {
49
63
  "type": "string",
50
64
  "enum": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shiftwork_status",
3
3
  "title": "Shift work: status",
4
- "description": "Shift-work status: where ONE checkpoint file stands — units counted by status, the unit plan.cursor points at, how many handoff.open_questions are waiting, and the last history entry. Call it first when resuming a job or answering 'where is job X'; it is the cheap read before any clock-in. It does not say WHICH units may run now — that is shiftwork_plan, the dependency batches — and it says nothing about the server itself, which is bantamkit_status. Every fact is read from the checkpoint on this call, nothing is cached, and a checkpoint that is missing, not valid JSON or failing the checkpoint schema answers {\"result\": \"error\", \"reason\": \"<sentence>\"} instead of a partial summary — the same refusals shiftwork_plan and shiftwork_clock_in give for that file. Opens only the checkpoint; writes nothing, not even the log shiftwork_clock_in appends to.",
4
+ "description": "Shift-work status: where ONE checkpoint file stands — units counted by status, the unit plan.cursor points at, how many handoff.open_questions are waiting, and the last history entry. Call it first when resuming a job or answering 'where is job X'; it is the cheap read before any clock-in. It does not say WHICH units may run now — that is shiftwork_plan, the dependency batches — and it says nothing about the server itself, which is bantamkit_status. Every fact is read from the checkpoint on this call, nothing is cached, and a checkpoint that is missing, not valid JSON or failing the checkpoint schema answers {\"result\": \"error\", \"reason\": \"<sentence>\"} instead of a partial summary — the same refusals shiftwork_plan and shiftwork_clock_in give for that file. With `search`, it also returns the lines of jobs Retention archived under the checkpoint's .shiftwork/archive/ that hold every word of the query. Opens only the checkpoint (and that archive directory when `search` is given); writes nothing, not even the log shiftwork_clock_in appends to.",
5
5
  "surfaces": [
6
6
  "mcp"
7
7
  ],
@@ -11,6 +11,10 @@
11
11
  "title": "Checkpoint",
12
12
  "type": "string",
13
13
  "description": "Path to the shift-work checkpoint JSON file (by convention .shiftwork/checkpoint.json in the repo the job works on), absolute or relative to the server's working directory. The same file shiftwork_plan, shiftwork_clock_in and shiftwork_clock_out take; it must validate against assets/schemas/shiftwork-checkpoint.json."
14
+ },
15
+ "search": {
16
+ "type": "string",
17
+ "description": "Also search jobs Retention archived under this checkpoint's .shiftwork/archive/: every line holding all the query's words, as {job, file, line}."
14
18
  }
15
19
  },
16
20
  "required": [
@@ -53,6 +57,27 @@
53
57
  ],
54
58
  "description": "The newest entry of the 5-entry history ring ({unit, outcome, notes?, ...}), or null when the ring is empty."
55
59
  },
60
+ "search": {
61
+ "type": "array",
62
+ "items": {
63
+ "type": "object",
64
+ "properties": {
65
+ "job": {
66
+ "type": "string",
67
+ "description": "The archived job the line belongs to."
68
+ },
69
+ "file": {
70
+ "type": "string",
71
+ "description": "Path of the archived file, relative to the job."
72
+ },
73
+ "line": {
74
+ "type": "integer",
75
+ "description": "1-based line number within that file."
76
+ }
77
+ }
78
+ },
79
+ "description": "Only when `search` was given: every archived line holding all its words, as {job, file, line}."
80
+ },
56
81
  "reason": {
57
82
  "type": "string",
58
83
  "description": "With result `error`: one sentence saying why the call was refused."
@@ -29,4 +29,4 @@ from bantamkit.structured import StructuredOutputError, extract_json, structured
29
29
  # file as its dynamic version source, so the wheel's metadata and the string the MCP
30
30
  # server advertises are the same committed bytes, and neither is a function of when
31
31
  # someone last ran `pip`.
32
- __version__ = "0.36.2"
32
+ __version__ = "0.37.0"
@@ -30,12 +30,13 @@ THREE HARD RULES, each with the failure it prevents:
30
30
  byte-compares both runtimes' streams; one stray write breaks the wire suite. Nothing
31
31
  in this module touches `sys.stderr` or `sys.stdout`.
32
32
  * **Metadata only.** Never a tool argument's value, never a memory body, never a
33
- validated output, never a query, never a document row. Nine of the fourteen tools take
33
+ validated output, never a query, never a document row. Nine of the fifteen tools take
34
34
  an unbounded string (counted over `assets/tools/`: a `string` parameter with no `enum`
35
35
  or `maxLength`, or an array of such; `bantamkit_read` and `repo_map` were two more until
36
- job50 I5 retired them from the roster — and `work_plan` is NOT one of them: its `nodes`
37
- is an array of objects, not an array of strings, so the rule does not reach the ids
38
- inside it) and among those `skill_audit`'s `root`,
36
+ job50 I5 retired them from the roster — and `work_plan` and `memory_queries` are NOT
37
+ among them: `nodes` and `facts` are arrays of objects, not arrays of strings, so the
38
+ rule does not reach the strings inside them; `memory_queries` records its `result`
39
+ token only) and among those `skill_audit`'s `root`,
39
40
  `token_ledger`'s `root` and `prices` and the four shift-work tools' `checkpoint` are
40
41
  absolute paths; each record carries counts and tokens from a closed set, never the
41
42
  path, never a part name, never a skill id, never a mapped file, never a session id,
@@ -72,6 +73,7 @@ from pathlib import Path
72
73
  from typing import Any
73
74
 
74
75
  from bantamkit.memory.store import bantamkit_dir_for, ensure_bantamkit_gitignore
76
+ from bantamkit.storage.logsegment import LogSegment
75
77
 
76
78
  #: Environment switch. Unset or `off`/`0`/`false`/`no`/empty -> disabled. `on`/`1`/
77
79
  #: `true`/`yes` -> the default file inside the memory store. Anything else is taken as
@@ -135,15 +137,23 @@ def encode_record(epoch_ms: int, tool: str, outcome: str, detail: dict[str, Any]
135
137
  module is non-ASCII today; the setting is what keeps that a fact about the data
136
138
  rather than a difference between the runtimes if it ever stops being one.
137
139
  """
138
- record = {
140
+ text = json.dumps(
141
+ _record_object(epoch_ms, tool, outcome, detail), ensure_ascii=False, separators=(",", ":")
142
+ )
143
+ return text.encode("utf-8") + b"\n"
144
+
145
+
146
+ def _record_object(
147
+ epoch_ms: int, tool: str, outcome: str, detail: dict[str, Any]
148
+ ) -> dict[str, Any]:
149
+ """The record `encode_record` spells, as the object `LogSegment.append` writes."""
150
+ return {
139
151
  "v": SCHEMA_VERSION,
140
152
  "ts": format_timestamp(epoch_ms),
141
153
  "tool": tool,
142
154
  "outcome": outcome,
143
155
  "detail": {key: detail[key] for key in sorted(detail)},
144
156
  }
145
- text = json.dumps(record, ensure_ascii=False, separators=(",", ":"))
146
- return text.encode("utf-8") + b"\n"
147
157
 
148
158
 
149
159
  def default_path(store_root: Path) -> Path:
@@ -266,9 +276,10 @@ class EventLog:
266
276
  """
267
277
  if self.path is None:
268
278
  return
269
- payload = encode_record(self._clock(), tool, outcome, detail or {})
279
+ obj = _record_object(self._clock(), tool, outcome, detail or {})
280
+ payload = json.dumps(obj, ensure_ascii=False, separators=(",", ":")).encode("utf-8") + b"\n"
270
281
  try:
271
- self._append(payload)
282
+ self._append(obj, payload)
272
283
  except OSError:
273
284
  self.write_failed = True
274
285
  return
@@ -282,8 +293,15 @@ class EventLog:
282
293
  """
283
294
  self.record(tool, "raised", {"type": type(exc).__name__})
284
295
 
285
- def _append(self, payload: bytes) -> None:
286
- """Rotate if this record would cross the cap, then append in BINARY mode.
296
+ def _append(self, obj: dict[str, Any], payload: bytes) -> None:
297
+ """Rotate if this record would cross the cap, then append through `LogSegment`.
298
+
299
+ #204 (J69-4): the line goes through `storage.LogSegment.append` (the shared O_EXCL
300
+ lock, a newline before a cut last line, the same bytes `encode_record` spells). THE
301
+ ROTATION RULE BELOW IS NOT `LogSegment.rotate`'s, on purpose: this log keeps exactly
302
+ one plain `<path>.1` that `--statusline` and `--mcp-report` read in both runtimes, and
303
+ a 2 MiB ceiling with no retention job behind it; docs/eventlog.md says one rotation
304
+ rule cannot be right for both this log and the hook log.
287
305
 
288
306
  Binary, not text: a text-mode write translates `\\n` to `os.linesep`, which is
289
307
  `\\r\\n` on Windows, and a Node reader byte-comparing the file would see a
@@ -332,5 +350,5 @@ class EventLog:
332
350
  size = 0
333
351
  if size and size + len(payload) > self.cap_bytes:
334
352
  os.replace(self.path, self.path.with_name(self.path.name + ".1"))
335
- with open(self.path, "ab") as handle:
336
- handle.write(payload)
353
+ if not LogSegment(self.path).append(obj):
354
+ raise OSError("the record could not be appended") # caught by `record`