brainiac-cli 0.20.44__tar.gz → 0.20.45__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 (360) hide show
  1. {brainiac_cli-0.20.44/src/brainiac_cli.egg-info → brainiac_cli-0.20.45}/PKG-INFO +1 -1
  2. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/pyproject.toml +1 -1
  3. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/brain-brief.sh +15 -0
  4. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_version.py +1 -1
  5. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/embed.py +7 -4
  6. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/embed_onnx.py +8 -4
  7. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_search.py +15 -10
  8. brainiac_cli-0.20.45/src/brain/model_slot.py +110 -0
  9. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/rerank.py +7 -4
  10. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/rerank_onnx.py +28 -4
  11. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/update_channels.py +11 -5
  12. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45/src/brainiac_cli.egg-info}/PKG-INFO +1 -1
  13. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brainiac_cli.egg-info/SOURCES.txt +1 -0
  14. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/LICENSE +0 -0
  15. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/MANIFEST.in +0 -0
  16. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/README.md +0 -0
  17. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/setup.cfg +0 -0
  18. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/__init__.py +0 -0
  19. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/__main__.py +0 -0
  20. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/AGENTS.md +0 -0
  21. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/assets/graph-explorer-template.html +0 -0
  22. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/overlay/template/brand/brand-guide.md +0 -0
  23. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/overlay/template/keywords/glossary.md +0 -0
  24. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/overlay/template/people/roster.md +0 -0
  25. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/overlay/template/voice/voice-profile.md +0 -0
  26. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/routines/manifest.json +0 -0
  27. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/brain-brief-mac.plist +0 -0
  28. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/brain-synthesis-mac.plist +0 -0
  29. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/brain-synthesis.sh +0 -0
  30. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/brain_synthesis_codex.py +0 -0
  31. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/brainiac-alerts.sh +0 -0
  32. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/brainiac-egress-guard.sh +0 -0
  33. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/install-brief-mac.sh +0 -0
  34. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/install-brief-windows.ps1 +0 -0
  35. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/register_tasks.py +0 -0
  36. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/vm-boundary-probe.sh +0 -0
  37. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/scripts/vm-selftest.sh +0 -0
  38. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/templates/company.md +0 -0
  39. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/templates/concept.md +0 -0
  40. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/templates/daily.md +0 -0
  41. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/templates/decision.md +0 -0
  42. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/templates/deliverable.md +0 -0
  43. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/templates/meeting.md +0 -0
  44. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/templates/person.md +0 -0
  45. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/templates/project.md +0 -0
  46. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_assets/templates/state-moc.md +0 -0
  47. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/_optional.py +0 -0
  48. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/alerts.py +0 -0
  49. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/alerts_render.py +0 -0
  50. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/alerts_staging.py +0 -0
  51. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/anchor.py +0 -0
  52. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/atomic_temp.py +0 -0
  53. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/attestation.py +0 -0
  54. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/audit.py +0 -0
  55. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/audit_chain.py +0 -0
  56. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/audit_drift.py +0 -0
  57. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/autolink.py +0 -0
  58. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/backup.py +0 -0
  59. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/brief.py +0 -0
  60. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/brief_render.py +0 -0
  61. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/capture.py +0 -0
  62. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/chunk.py +0 -0
  63. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/classification.py +0 -0
  64. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli.py +0 -0
  65. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/__init__.py +0 -0
  66. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/common_parser.py +0 -0
  67. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/connect.py +0 -0
  68. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/connect_parser.py +0 -0
  69. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/eval.py +0 -0
  70. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/eval_parser.py +0 -0
  71. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/index_storage.py +0 -0
  72. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/index_storage_parser.py +0 -0
  73. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/ingest_storage.py +0 -0
  74. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/ingest_storage_parser.py +0 -0
  75. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/lifecycle.py +0 -0
  76. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/lifecycle_parser.py +0 -0
  77. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/maintenance.py +0 -0
  78. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/maintenance_parser.py +0 -0
  79. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/navigation.py +0 -0
  80. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/navigation_parser.py +0 -0
  81. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/owner_workflow.py +0 -0
  82. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/owner_workflow_parser.py +0 -0
  83. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/presentation.py +0 -0
  84. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/presentation_parser.py +0 -0
  85. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/retrieval.py +0 -0
  86. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/retrieval_parser.py +0 -0
  87. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/update.py +0 -0
  88. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/update_parser.py +0 -0
  89. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/versioning.py +0 -0
  90. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_cmds/versioning_parser.py +0 -0
  91. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_help.py +0 -0
  92. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_read_record.py +0 -0
  93. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cli_render.py +0 -0
  94. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/config.py +0 -0
  95. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/config_hostpaths.py +0 -0
  96. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/connect.py +0 -0
  97. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/context.py +0 -0
  98. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/conventions.py +0 -0
  99. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/conventions_scan.py +0 -0
  100. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/__init__.py +0 -0
  101. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_audit.py +0 -0
  102. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_briefing.py +0 -0
  103. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_capture.py +0 -0
  104. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_capture_staging.py +0 -0
  105. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_durability.py +0 -0
  106. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_health.py +0 -0
  107. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_maintenance.py +0 -0
  108. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_maintenance_state.py +0 -0
  109. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_retrieval.py +0 -0
  110. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_shared.py +0 -0
  111. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_supersede_batch.py +0 -0
  112. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_supersession.py +0 -0
  113. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/core/_supersession_journal.py +0 -0
  114. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cowork_leak_artifact.py +0 -0
  115. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cowork_leak_databases.py +0 -0
  116. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cowork_leak_notes.py +0 -0
  117. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cowork_leak_scan.py +0 -0
  118. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cowork_snapshot_guard.py +0 -0
  119. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/cowork_staging.py +0 -0
  120. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/dbretry.py +0 -0
  121. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/deliverables_absorb.py +0 -0
  122. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/deliverables_apply.py +0 -0
  123. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/deliverables_ledger.py +0 -0
  124. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/deliverables_materialize.py +0 -0
  125. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/deliverables_previous.py +0 -0
  126. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/deliverables_readme.py +0 -0
  127. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/deliverables_shelf.py +0 -0
  128. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/deliverables_sync.py +0 -0
  129. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/doctor.py +0 -0
  130. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/doctor_checks.py +0 -0
  131. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/doctor_context.py +0 -0
  132. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/doctor_desktop.py +0 -0
  133. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/doctor_health.py +0 -0
  134. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/doctor_mount_leak.py +0 -0
  135. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/doctor_plugins.py +0 -0
  136. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/doctor_staging.py +0 -0
  137. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/doctor_vendor.py +0 -0
  138. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/doctor_vm.py +0 -0
  139. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/doctor_wiring.py +0 -0
  140. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/draft_drain.py +0 -0
  141. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/draft_update.py +0 -0
  142. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/egress.py +0 -0
  143. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/egress_terms.py +0 -0
  144. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/embed_backends.py +0 -0
  145. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/embed_catalog.py +0 -0
  146. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/embed_qwen.py +0 -0
  147. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/encryption.py +0 -0
  148. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/exceptions_cli.py +0 -0
  149. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/exceptions_page.py +0 -0
  150. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/exceptions_render.py +0 -0
  151. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/exceptions_tray.py +0 -0
  152. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/exceptions_verify.py +0 -0
  153. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/__init__.py +0 -0
  154. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/context.py +0 -0
  155. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/daily.py +0 -0
  156. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/deliverables.py +0 -0
  157. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/golden.py +0 -0
  158. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/graph.py +0 -0
  159. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/intake.py +0 -0
  160. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/invariants.py +0 -0
  161. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/orchestrator.py +0 -0
  162. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/organization.py +0 -0
  163. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/preflight.py +0 -0
  164. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/publish.py +0 -0
  165. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/remediation.py +0 -0
  166. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/remediation_bookkeeping.py +0 -0
  167. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/reporting.py +0 -0
  168. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/retention.py +0 -0
  169. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/watchdogs.py +0 -0
  170. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/folds/weekly.py +0 -0
  171. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/frontmatter.py +0 -0
  172. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/golden_ops.py +0 -0
  173. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/golden_probe.py +0 -0
  174. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/golden_probe_cases.py +0 -0
  175. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/graph.py +0 -0
  176. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/graph_hygiene.py +0 -0
  177. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/graph_ops.py +0 -0
  178. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/graphify.py +0 -0
  179. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/graphify_edges.py +0 -0
  180. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/graphreport.py +0 -0
  181. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/graphreport_sections.py +0 -0
  182. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/graphreport_sections_2.py +0 -0
  183. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/guard_settings.py +0 -0
  184. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/healthreport.py +0 -0
  185. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/healthreport_sections.py +0 -0
  186. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/healthreport_unsigned.py +0 -0
  187. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/inbox.py +0 -0
  188. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/__init__.py +0 -0
  189. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_connection.py +0 -0
  190. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_families.py +0 -0
  191. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_graph.py +0 -0
  192. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_identity.py +0 -0
  193. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_lifecycle.py +0 -0
  194. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_models.py +0 -0
  195. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_planning.py +0 -0
  196. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_records.py +0 -0
  197. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_retirement.py +0 -0
  198. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_schema.py +0 -0
  199. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_settings.py +0 -0
  200. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_shared.py +0 -0
  201. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_tools.py +0 -0
  202. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index/_zones.py +0 -0
  203. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/__init__.py +0 -0
  204. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/connection.py +0 -0
  205. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/diagnostics.py +0 -0
  206. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/duplicate_families.py +0 -0
  207. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/near_duplicates.py +0 -0
  208. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/rebuild.py +0 -0
  209. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/reranking.py +0 -0
  210. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/search.py +0 -0
  211. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/search_finalization.py +0 -0
  212. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/search_identity.py +0 -0
  213. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/search_ranking.py +0 -0
  214. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/index_stages/sync.py +0 -0
  215. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/__init__.py +0 -0
  216. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/deliverables.py +0 -0
  217. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/__init__.py +0 -0
  218. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/base.py +0 -0
  219. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/concealment.py +0 -0
  220. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/concealment_gate.py +0 -0
  221. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/concealment_html.py +0 -0
  222. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/concealment_ledger.py +0 -0
  223. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/concealment_office.py +0 -0
  224. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/concealment_pdf.py +0 -0
  225. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/docx.py +0 -0
  226. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/email.py +0 -0
  227. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/html.py +0 -0
  228. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/image.py +0 -0
  229. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/ole.py +0 -0
  230. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/pdf.py +0 -0
  231. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/pptx.py +0 -0
  232. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/tables.py +0 -0
  233. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/text.py +0 -0
  234. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/xlsx.py +0 -0
  235. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/handlers/zip.py +0 -0
  236. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/pipeline.py +0 -0
  237. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/pipeline_duplicates.py +0 -0
  238. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/pipeline_files.py +0 -0
  239. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/pipeline_injection.py +0 -0
  240. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/pipeline_nested.py +0 -0
  241. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/pipeline_run.py +0 -0
  242. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/pipeline_stages.py +0 -0
  243. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/tierguard.py +0 -0
  244. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/tierguard_verdict.py +0 -0
  245. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/ingest/transcript.py +0 -0
  246. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/init.py +0 -0
  247. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/init_import.py +0 -0
  248. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/init_samples.py +0 -0
  249. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/init_seed.py +0 -0
  250. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/init_steps.py +0 -0
  251. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/injection_fold.py +0 -0
  252. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/injection_scan.py +0 -0
  253. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/interview.py +0 -0
  254. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/interview_apply.py +0 -0
  255. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/interview_detect.py +0 -0
  256. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/invariant_coverage.py +0 -0
  257. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/invariant_crosstier.py +0 -0
  258. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/invariant_deliverables.py +0 -0
  259. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/invariant_floors.py +0 -0
  260. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/invariant_ingest_guard.py +0 -0
  261. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/invariant_lane_health.py +0 -0
  262. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/invariant_reachability.py +0 -0
  263. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/invariant_shared.py +0 -0
  264. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/invariant_unsigned_notes.py +0 -0
  265. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/invariants.py +0 -0
  266. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/invariants_metrics.py +0 -0
  267. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/language.py +0 -0
  268. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/link_targets.py +0 -0
  269. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/lock.py +0 -0
  270. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance.py +0 -0
  271. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_escalation.py +0 -0
  272. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_folds.py +0 -0
  273. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_folds_2.py +0 -0
  274. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_folds_3.py +0 -0
  275. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_folds_4.py +0 -0
  276. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_golden.py +0 -0
  277. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_graphfolds.py +0 -0
  278. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_healthlog.py +0 -0
  279. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_hotmd.py +0 -0
  280. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_invariant_fields.py +0 -0
  281. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_notify.py +0 -0
  282. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_outcomes.py +0 -0
  283. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_para.py +0 -0
  284. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_recommendations.py +0 -0
  285. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_retention.py +0 -0
  286. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_sweep.py +0 -0
  287. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/maintenance_watchdog.py +0 -0
  288. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_adapter.py +0 -0
  289. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_capture_verbs.py +0 -0
  290. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_housekeeping_verbs.py +0 -0
  291. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_mediation.py +0 -0
  292. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_supersede_verbs.py +0 -0
  293. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_tools/__init__.py +0 -0
  294. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_tools/capture.py +0 -0
  295. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_tools/core_read.py +0 -0
  296. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_tools/housekeeping.py +0 -0
  297. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_tools/retrieval.py +0 -0
  298. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_tools/supersession.py +0 -0
  299. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/mcp_verbs.py +0 -0
  300. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/multihop.py +0 -0
  301. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/notes.py +0 -0
  302. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/originals_resolve.py +0 -0
  303. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/overlay.py +0 -0
  304. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/overlay_core.py +0 -0
  305. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/overlay_generated.py +0 -0
  306. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/overlay_keywords.py +0 -0
  307. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/overlay_rules.py +0 -0
  308. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/pathkey.py +0 -0
  309. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/progress.py +0 -0
  310. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/projection.py +0 -0
  311. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/provenance.py +0 -0
  312. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/provision.py +0 -0
  313. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/provision_mcp.py +0 -0
  314. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/provision_stage.py +0 -0
  315. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/provision_wire.py +0 -0
  316. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/querylog.py +0 -0
  317. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/querylog_digest.py +0 -0
  318. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/querylog_replay.py +0 -0
  319. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/querylog_status.py +0 -0
  320. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/read_log.py +0 -0
  321. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/reexec.py +0 -0
  322. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation.py +0 -0
  323. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation_answers.py +0 -0
  324. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation_branches.py +0 -0
  325. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation_converged.py +0 -0
  326. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation_exceptions.py +0 -0
  327. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation_exceptions_store.py +0 -0
  328. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation_extract_retry.py +0 -0
  329. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation_folds.py +0 -0
  330. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation_questions.py +0 -0
  331. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation_routing.py +0 -0
  332. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation_schema.py +0 -0
  333. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/remediation_state.py +0 -0
  334. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/retrieval_ops.py +0 -0
  335. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/retro.py +0 -0
  336. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/session_hook.py +0 -0
  337. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/session_hook_settings.py +0 -0
  338. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/session_hook_spec.py +0 -0
  339. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/snapshot.py +0 -0
  340. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/status_ops.py +0 -0
  341. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/supersede_declared.py +0 -0
  342. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/sweepdirs.py +0 -0
  343. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/update.py +0 -0
  344. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/update_channels_2.py +0 -0
  345. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/update_cos_guard.py +0 -0
  346. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/update_model.py +0 -0
  347. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/update_ops.py +0 -0
  348. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/update_plugins.py +0 -0
  349. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/update_state.py +0 -0
  350. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/update_venv.py +0 -0
  351. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/vectors.py +0 -0
  352. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/versionlink.py +0 -0
  353. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/versionlink_stages.py +0 -0
  354. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/vm_ceiling.py +0 -0
  355. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/vmstaging.py +0 -0
  356. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brain/workspaces.py +0 -0
  357. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brainiac_cli.egg-info/dependency_links.txt +0 -0
  358. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brainiac_cli.egg-info/entry_points.txt +0 -0
  359. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brainiac_cli.egg-info/requires.txt +0 -0
  360. {brainiac_cli-0.20.44 → brainiac_cli-0.20.45}/src/brainiac_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brainiac-cli
3
- Version: 0.20.44
3
+ Version: 0.20.45
4
4
  Summary: Brainiac — local any-LLM second-brain core engine + brain CLI (Markdown truth, derived SQLite index).
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Homepage, https://github.com/Autopsias/brainiac
@@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"
8
8
  # check. The IMPORT package stays `brain` and the console script stays
9
9
  # `brain` — only the distribution/project name changes.
10
10
  name = "brainiac-cli"
11
- version = "0.20.44"
11
+ version = "0.20.45"
12
12
  description = "Brainiac — local any-LLM second-brain core engine + brain CLI (Markdown truth, derived SQLite index)."
13
13
  readme = "README.md"
14
14
  license = "Apache-2.0"
@@ -61,6 +61,21 @@ if [ -z "$BRAIN_BIN" ]; then
61
61
  exit 1
62
62
  fi
63
63
 
64
+ # YIELD TO THE NIGHTLY MAIL RUN (2026-10-19). Both do model work, and the
65
+ # machine runs at most $BRAIN_MODEL_SLOTS (2) model processes at once. On
66
+ # run374 an hourly maintain ran 02:06-03:04 across the run's grounding window
67
+ # and 58 of 72 sender lookups timed out (0 of 122 the night before). The night
68
+ # runs its own broker after its child exits, so skipping an hour loses
69
+ # nothing: the next hourly run catches up. A hung night also stops this job;
70
+ # the WAT-01 stale-feed alert names it after 2 days.
71
+ # ponytail: process-name match, a pid lock if the night ever runs under
72
+ # another name.
73
+ YIELD_TO="${BRAIN_BRIEF_YIELD_TO:-tools/cos_nightly.sh}"
74
+ if pgrep -f "$YIELD_TO" >/dev/null 2>&1; then
75
+ echo "=== brain-daily-brief / brain-nightly $(date -u +%Y-%m-%dT%H:%M:%SZ) === SKIP: the nightly mail run is running ($YIELD_TO); next hour catches up" >> "$LOG"
76
+ exit 0
77
+ fi
78
+
64
79
  # The RUN VALIDATOR needs the mutation toolchain, and the wheel does not carry
65
80
  # it (2026-08-22). `brain.cos_runverify.check_plan_binding` imports
66
81
  # `cos_mutate.load_frozen_plan` to re-hash a run's frozen plan — one definition
@@ -9,4 +9,4 @@ pip-installed host, importlib.metadata stays primary; brain/__init__.py reads
9
9
  this file only as the fallback before 0.0.0+unknown.
10
10
  """
11
11
 
12
- __version__ = "0.20.44"
12
+ __version__ = "0.20.45"
@@ -50,18 +50,21 @@ ARCTIC_FULL_DIM = 768
50
50
  MRL_DIM = 256
51
51
 
52
52
 
53
+ # Measured 2026-10-19: 4 threads match the all-cores wall time at ~40% of the CPU.
54
+ _DEFAULT_THREADS = 4
55
+
56
+
53
57
  def _ort_threads() -> int | None:
54
58
  """Intra-op thread count for the ONNX session (S11 speed fix).
55
59
 
56
- Default: all physical cores (Apple Silicon has no SMT, so logical ==
57
- physical — on the M4 Pro that is 12). Saturating the batch dimension
58
- across cores is the biggest ORT knob for bulk embedding throughput.
60
+ Default: 4 threads (capped at the core count). More threads spin without
61
+ cutting wall time; raise it for bulk work.
59
62
  Override via ``$BRAIN_EMBED_THREADS``."""
60
63
  raw = os.environ.get("BRAIN_EMBED_THREADS")
61
64
  if raw and raw.strip().isdigit():
62
65
  return int(raw)
63
66
  try:
64
- return os.cpu_count() or None
67
+ return min(_DEFAULT_THREADS, os.cpu_count() or _DEFAULT_THREADS)
65
68
  except Exception:
66
69
  return None
67
70
 
@@ -8,6 +8,8 @@ import sys as sys
8
8
  from dataclasses import dataclass
9
9
  from typing import Sequence
10
10
 
11
+ from .model_slot import model_slot
12
+
11
13
  # --- Direct-ONNX models (DIST-01: eliminates fastembed) ---------------------
12
14
  # Each model owns its pooling, prefixes, dimension and exact file. Keeping the
13
15
  # contract here prevents a future model swap from inheriting another model's
@@ -255,9 +257,10 @@ class OnnxEmbedder:
255
257
  t = _ort_threads()
256
258
  if t:
257
259
  so.intra_op_num_threads = t
258
- self._sess = ort.InferenceSession(
259
- onnx_path, sess_options=so, providers=_ort_providers()
260
- )
260
+ with model_slot(): # loading peaks well above the weights' size
261
+ self._sess = ort.InferenceSession(
262
+ onnx_path, sess_options=so, providers=_ort_providers()
263
+ )
261
264
  self._in_names = [i.name for i in self._sess.get_inputs()]
262
265
  self._tok = Tokenizer.from_file(os.path.join(base, "tokenizer.json"))
263
266
  # Truncate to the engine's calibrated chunk window BEFORE padding.
@@ -387,7 +390,8 @@ class OnnxEmbedder:
387
390
  feed[nm] = am
388
391
  elif "token_type" in low:
389
392
  feed[nm] = np.zeros_like(ii)
390
- hidden = self._sess.run(None, feed)[0] # [batch, seq, dim] float32
393
+ with model_slot():
394
+ hidden = self._sess.run(None, feed)[0] # [batch, seq, dim] float32
391
395
  if self._pooling == "cls":
392
396
  pooled = hidden[:, 0, :]
393
397
  else:
@@ -2,6 +2,7 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  from ._shared import * # noqa: F401,F403
5
+ from ..model_slot import model_slot
5
6
 
6
7
 
7
8
  class _SearchMixin:
@@ -150,11 +151,14 @@ class _SearchMixin:
150
151
 
151
152
  Retired versions (``is_latest_version: false``) are hidden unless
152
153
  ``include_retired`` — see ``search_ranking.generate_candidates``."""
153
- return self._hybrid_search_impl(
154
- query, k=k, rrf_k=rrf_k, candidate_factor=candidate_factor,
155
- rerank=rerank, reranker=reranker, rerank_top=rerank_top,
156
- rerank_gate=rerank_gate, trace=None, include_retired=include_retired,
157
- )
154
+ # The slot is taken HERE, before the reranker's 30 s budget starts, so
155
+ # a queued search waits instead of silently losing its rerank.
156
+ with model_slot():
157
+ return self._hybrid_search_impl(
158
+ query, k=k, rrf_k=rrf_k, candidate_factor=candidate_factor,
159
+ rerank=rerank, reranker=reranker, rerank_top=rerank_top,
160
+ rerank_gate=rerank_gate, trace=None, include_retired=include_retired,
161
+ )
158
162
 
159
163
  def hybrid_search_with_trace(
160
164
  self,
@@ -187,11 +191,12 @@ class _SearchMixin:
187
191
  candidate_limit=n,
188
192
  result_limit=max(0, k),
189
193
  )
190
- hits = self._hybrid_search_impl(
191
- query, k=k, rrf_k=rrf_k, candidate_factor=candidate_factor,
192
- rerank=rerank, reranker=reranker, rerank_top=rerank_top,
193
- rerank_gate=rerank_gate, trace=trace, include_retired=include_retired,
194
- )
194
+ with model_slot(): # see hybrid_search
195
+ hits = self._hybrid_search_impl(
196
+ query, k=k, rrf_k=rrf_k, candidate_factor=candidate_factor,
197
+ rerank=rerank, reranker=reranker, rerank_top=rerank_top,
198
+ rerank_gate=rerank_gate, trace=trace, include_retired=include_retired,
199
+ )
195
200
  return hits, trace
196
201
 
197
202
  def _hybrid_search_impl(
@@ -0,0 +1,110 @@
1
+ """Machine-wide cap on concurrent model work (load + inference).
2
+
3
+ WHY. One `brain search` peaks at ~4 GB for a few seconds: loading the fp32
4
+ reranker alone measures 3.0 GB, a 15-pair rerank adds ~1 GB (measured
5
+ 2026-10-18, M4 Pro). On 2026-10-18 three subagents ran ten searches at once on
6
+ a 24 GB Mac; macOS recorded ten Python processes at 4.1-6.8 GB each and the
7
+ machine froze until a forced reset. Jetsam stopped only small system daemons,
8
+ never the searches. Nothing in brain bounded how many ran together.
9
+
10
+ WHAT. `model_slot()` waits for one of `$BRAIN_MODEL_SLOTS` (default 2) slot
11
+ files under `$BRAIN_MODEL_SLOT_DIR` (default ~/.cache/brain-model-slots) and
12
+ holds an exclusive `flock` on it for the duration of the block. The kernel drops
13
+ the lock when the process dies, so a crash never leaks a slot.
14
+
15
+ RE-ENTRANT PER PROCESS. A search holds a slot and its reranker worker thread
16
+ runs inside it; that work must not wait for a second slot. So the first
17
+ acquire in a process takes a slot, and nested or concurrent acquires in the
18
+ same process ride on it until the depth returns to zero. The cap is therefore
19
+ "processes doing model work", which is what costs memory.
20
+
21
+ FAIL OPEN. If the slot directory cannot be created or opened (read-only HOME,
22
+ Windows without fcntl), the work runs unguarded: a guard must never stop a
23
+ search from working. ponytail: no Windows lock — add msvcrt when a Windows
24
+ host runs parallel searches.
25
+ """
26
+ from __future__ import annotations
27
+
28
+ import contextlib
29
+ import os
30
+ import sys
31
+ import threading
32
+ import time
33
+ from pathlib import Path
34
+ from typing import Iterator
35
+
36
+ try:
37
+ import fcntl
38
+ except ImportError: # Windows
39
+ fcntl = None # type: ignore[assignment]
40
+
41
+ _POLL_SECONDS = 0.2
42
+ _gate = threading.Lock() # a second thread waits here while the first acquires
43
+ _state = threading.Lock()
44
+ _depth = 0
45
+ _fd: int | None = None
46
+
47
+
48
+ def slot_count() -> int:
49
+ raw = os.environ.get("BRAIN_MODEL_SLOTS", "").strip()
50
+ return int(raw) if raw.isdigit() and int(raw) > 0 else 2
51
+
52
+
53
+ def slot_dir() -> Path:
54
+ raw = os.environ.get("BRAIN_MODEL_SLOT_DIR")
55
+ return Path(raw) if raw else Path.home() / ".cache" / "brain-model-slots"
56
+
57
+
58
+ def _try_take(paths: list[Path]) -> int | None:
59
+ for path in paths:
60
+ fd = os.open(path, os.O_RDWR | os.O_CREAT, 0o644)
61
+ try:
62
+ fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
63
+ except OSError:
64
+ os.close(fd)
65
+ continue
66
+ return fd
67
+ return None
68
+
69
+
70
+ def _acquire() -> int | None:
71
+ if fcntl is None:
72
+ return None
73
+ try:
74
+ root = slot_dir()
75
+ root.mkdir(parents=True, exist_ok=True)
76
+ paths = [root / f"slot-{i}.lock" for i in range(slot_count())]
77
+ fd = _try_take(paths)
78
+ if fd is not None:
79
+ return fd
80
+ print(f"brain: waiting for a model slot ({len(paths)} in use on this "
81
+ "machine; $BRAIN_MODEL_SLOTS sets the cap)", file=sys.stderr, flush=True)
82
+ while fd is None:
83
+ time.sleep(_POLL_SECONDS)
84
+ fd = _try_take(paths)
85
+ return fd
86
+ except OSError as exc:
87
+ print(f"brain: model slot unavailable ({exc}); running unguarded",
88
+ file=sys.stderr, flush=True)
89
+ return None
90
+
91
+
92
+ @contextlib.contextmanager
93
+ def model_slot() -> Iterator[None]:
94
+ global _depth, _fd
95
+ with _gate:
96
+ with _state:
97
+ first = _depth == 0
98
+ fd = _acquire() if first else None # a KeyboardInterrupt here holds nothing
99
+ with _state:
100
+ _depth += 1
101
+ if first:
102
+ _fd = fd
103
+ try:
104
+ yield
105
+ finally:
106
+ with _state:
107
+ _depth -= 1
108
+ if _depth == 0 and _fd is not None:
109
+ os.close(_fd) # closing the only fd on the file drops the flock
110
+ _fd = None
@@ -40,18 +40,21 @@ import os
40
40
  from typing import Protocol, Sequence, runtime_checkable
41
41
 
42
42
 
43
+ # Measured 2026-10-19: 4 threads match the all-cores wall time at ~40% of the CPU.
44
+ _DEFAULT_THREADS = 4
45
+
46
+
43
47
  def _ort_threads() -> int | None:
44
48
  """Intra-op thread count for the reranker ONNX session (S11 speed fix).
45
49
 
46
- Default: all physical cores. The reranker cross-encodes the top-N
47
- (query, passage) pairs in ONE batched forward pass, so saturating the
48
- batch dimension across cores is what keeps query p95 interactive.
50
+ Default: 4 threads (capped at the core count). More threads spin without
51
+ cutting wall time; raise it for bulk work.
49
52
  Override via ``$BRAIN_RERANK_THREADS``."""
50
53
  raw = os.environ.get("BRAIN_RERANK_THREADS")
51
54
  if raw and raw.strip().isdigit():
52
55
  return int(raw)
53
56
  try:
54
- return os.cpu_count() or None
57
+ return min(_DEFAULT_THREADS, os.cpu_count() or _DEFAULT_THREADS)
55
58
  except Exception:
56
59
  return None
57
60
 
@@ -4,6 +4,8 @@ from __future__ import annotations
4
4
  import os
5
5
  from typing import Sequence
6
6
 
7
+ from .model_slot import model_slot
8
+
7
9
  # --- Fully-open reranker of record (replaces the CC-BY-NC jina-reranker-v2) ---
8
10
  # gte-multilingual-reranker-base is Apache-2.0, an XLM-R ENCODER cross-encoder
9
11
  # (~306M). It is the best QUALITY among the latency-affordable fully-open
@@ -178,9 +180,10 @@ class OnnxReranker:
178
180
  t = _ort_threads()
179
181
  if t:
180
182
  so.intra_op_num_threads = t
181
- self._sess = ort.InferenceSession(
182
- onnx_path, sess_options=so, providers=_ort_providers()
183
- )
183
+ with model_slot(): # this load alone peaks at 3.0 GB
184
+ self._sess = ort.InferenceSession(
185
+ onnx_path, sess_options=so, providers=_ort_providers()
186
+ )
184
187
  self._in_names = [i.name for i in self._sess.get_inputs()]
185
188
  self._tok = Tokenizer.from_file(os.path.join(base, "tokenizer.json"))
186
189
  # Clamp (query, passage) pairs to the cross-encoder's context
@@ -222,6 +225,20 @@ class OnnxReranker:
222
225
  if not passages:
223
226
  return []
224
227
  self._ensure()
228
+ # Score in small batches, not all passages at once. Working memory
229
+ # grows with batch x seq^2 (self-attention over 1024-token pairs):
230
+ # one 15-20 pair batch peaked a search at ~4 GB, a long-lived MCP
231
+ # server retained 12 GB after 15 searches, and ten parallel searches
232
+ # froze a 24 GB Mac (2026-10-18). Scores are unchanged: each pad
233
+ # position is masked out of attention. Override via
234
+ # $BRAIN_RERANK_BATCH.
235
+ size = _rerank_batch()
236
+ scores: list[float] = []
237
+ for start in range(0, len(passages), size):
238
+ scores.extend(self._score(query, passages[start:start + size]))
239
+ return scores
240
+
241
+ def _score(self, query: str, passages: Sequence[str]) -> list[float]:
225
242
  import numpy as np
226
243
 
227
244
  enc = self._tok.encode_batch([(query, p) for p in passages])
@@ -236,9 +253,16 @@ class OnnxReranker:
236
253
  feed[nm] = am
237
254
  elif "token_type" in low:
238
255
  feed[nm] = np.zeros_like(ii)
239
- logits = self._sess.run(None, feed)[0]
256
+ with model_slot():
257
+ logits = self._sess.run(None, feed)[0]
240
258
  return [float(x[0]) if hasattr(x, "__len__") else float(x) for x in logits]
241
259
 
260
+
261
+ def _rerank_batch() -> int:
262
+ """Pairs per reranker run (default 4). See `OnnxReranker.rerank`."""
263
+ raw = os.environ.get("BRAIN_RERANK_BATCH", "")
264
+ return int(raw) if raw.strip().isdigit() and int(raw) > 0 else 4
265
+
242
266
  # Parent-namespace binds, deferred past this module's own defs (circular-import
243
267
  # safety, whichever of brain.rerank / brain.rerank_onnx loads first).
244
268
  from .rerank import RerankerUnavailable as RerankerUnavailable # noqa: E402
@@ -31,6 +31,12 @@ from .update_cos_guard import (
31
31
  #: old version — silently, because the crash pre-empted the report.
32
32
  WORKSPACE_SYNC_TIMEOUT_S = 1800
33
33
 
34
+ #: The engine reinstall is a real pip/uv/pipx install, and it too borrowed the
35
+ #: shared 120s default. Measured 2026-10-17 on the v0.20.44 release: the venv
36
+ #: install of the checkout (new mcp dependency set) took 6m39s, so `brain
37
+ #: update` returned {"error": "TimeoutExpired"} before it re-staged anything.
38
+ ENGINE_INSTALL_TIMEOUT_S = 1800
39
+
34
40
  Runner = Callable[..., subprocess.CompletedProcess[str]]
35
41
  ChannelDetector = Callable[[Optional[Path]], str]
36
42
  VenvBinResolver = Callable[[Path, str], Path]
@@ -63,12 +69,12 @@ def _read_installed_version(
63
69
 
64
70
  def upgrade_uv_tool(run: Runner) -> subprocess.CompletedProcess[str]:
65
71
  """Upgrade the uv-managed distribution."""
66
- return run(["uv", "tool", "upgrade", "brainiac-cli"])
72
+ return run(["uv", "tool", "upgrade", "brainiac-cli"], timeout=ENGINE_INSTALL_TIMEOUT_S)
67
73
 
68
74
 
69
75
  def upgrade_pipx(run: Runner) -> subprocess.CompletedProcess[str]:
70
76
  """Upgrade the pipx-managed distribution."""
71
- return run(["pipx", "upgrade", "brainiac-cli"])
77
+ return run(["pipx", "upgrade", "brainiac-cli"], timeout=ENGINE_INSTALL_TIMEOUT_S)
72
78
 
73
79
 
74
80
  def upgrade_pip_user(
@@ -84,7 +90,7 @@ def upgrade_pip_user(
84
90
  "--user",
85
91
  "--upgrade",
86
92
  "brainiac-cli[mcp]",
87
- ])
93
+ ], timeout=ENGINE_INSTALL_TIMEOUT_S)
88
94
 
89
95
 
90
96
  def upgrade_venv_wheel(
@@ -93,7 +99,7 @@ def upgrade_venv_wheel(
93
99
  target: str,
94
100
  ) -> subprocess.CompletedProcess[str]:
95
101
  """Upgrade a non-editable wheel inside the legacy venv."""
96
- return run([str(pip_path), "install", "--upgrade", target])
102
+ return run([str(pip_path), "install", "--upgrade", target], timeout=ENGINE_INSTALL_TIMEOUT_S)
97
103
 
98
104
 
99
105
  def upgrade_editable(
@@ -102,7 +108,7 @@ def upgrade_editable(
102
108
  engine_src: Path,
103
109
  ) -> subprocess.CompletedProcess[str]:
104
110
  """Upgrade the editable checkout inside the legacy venv."""
105
- return run([str(pip_path), "install", "--upgrade", "-e", f"{engine_src}[mcp]"])
111
+ return run([str(pip_path), "install", "--upgrade", "-e", f"{engine_src}[mcp]"], timeout=ENGINE_INSTALL_TIMEOUT_S)
106
112
 
107
113
 
108
114
  def refresh_engine_channel(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brainiac-cli
3
- Version: 0.20.44
3
+ Version: 0.20.45
4
4
  Summary: Brainiac — local any-LLM second-brain core engine + brain CLI (Markdown truth, derived SQLite index).
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Homepage, https://github.com/Autopsias/brainiac
@@ -138,6 +138,7 @@ src/brain/mcp_housekeeping_verbs.py
138
138
  src/brain/mcp_mediation.py
139
139
  src/brain/mcp_supersede_verbs.py
140
140
  src/brain/mcp_verbs.py
141
+ src/brain/model_slot.py
141
142
  src/brain/multihop.py
142
143
  src/brain/notes.py
143
144
  src/brain/originals_resolve.py
File without changes
File without changes
File without changes