brindle 0.4.6__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. {brindle-0.4.6 → brindle-0.5.0}/PKG-INFO +64 -73
  2. {brindle-0.4.6 → brindle-0.5.0}/README.md +63 -72
  3. {brindle-0.4.6 → brindle-0.5.0}/pyproject.toml +1 -1
  4. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/agents.py +189 -108
  5. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/antigravity.py +12 -15
  6. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/cli.py +31 -7
  7. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/api-schema.json +2734 -2430
  8. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/app.py +1 -4
  9. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/holds.py +6 -0
  10. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/routes_actions.py +216 -26
  11. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/routes_read.py +28 -12
  12. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/db.py +6 -0
  13. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/native/permissions.py +2 -1
  14. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/native/runner.py +11 -9
  15. brindle-0.5.0/src/brindle/permission_grants.py +799 -0
  16. brindle-0.5.0/src/brindle/permissions.py +3129 -0
  17. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/providers.py +40 -9
  18. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/service/dto.py +179 -115
  19. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/service/inbox.py +4 -131
  20. brindle-0.5.0/src/brindle/service/permissions.py +135 -0
  21. brindle-0.4.6/src/brindle/daemon/grants.py +0 -320
  22. brindle-0.4.6/src/brindle/daemon/routes_permissions.py +0 -37
  23. brindle-0.4.6/src/brindle/permission_editor.py +0 -350
  24. brindle-0.4.6/src/brindle/permission_grants.py +0 -646
  25. brindle-0.4.6/src/brindle/permissions.py +0 -1870
  26. {brindle-0.4.6 → brindle-0.5.0}/.gitignore +0 -0
  27. {brindle-0.4.6 → brindle-0.5.0}/LICENSE +0 -0
  28. {brindle-0.4.6 → brindle-0.5.0}/SCHEDULE-A +0 -0
  29. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/__init__.py +0 -0
  30. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/__main__.py +0 -0
  31. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/account.py +0 -0
  32. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/airgap.py +0 -0
  33. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/assembler.py +0 -0
  34. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/assets/braid_dark.png +0 -0
  35. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/assets/braid_light.png +0 -0
  36. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/autopilot.py +0 -0
  37. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/budget.py +0 -0
  38. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/__init__.py +0 -0
  39. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/backend-auditor.md +0 -0
  40. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/coordinator.md +0 -0
  41. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/developer-codex.md +0 -0
  42. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/developer-fable.md +0 -0
  43. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/developer-gemini.md +0 -0
  44. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/developer-heavy.md +0 -0
  45. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/developer-light.md +0 -0
  46. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/developer-local.md +0 -0
  47. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/developer-opencode.md +0 -0
  48. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/developer-sonnet.md +0 -0
  49. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/developer.md +0 -0
  50. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/qa.md +0 -0
  51. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/reviewer-codex.md +0 -0
  52. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/reviewer-gemini.md +0 -0
  53. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/reviewer-local.md +0 -0
  54. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/reviewer-opencode.md +0 -0
  55. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/reviewer.md +0 -0
  56. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/subagent.md +0 -0
  57. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_agents/supervisor.md +0 -0
  58. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_rules/__init__.py +0 -0
  59. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_rules/security/backend.md +0 -0
  60. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_rules/style/minimal-diff.md +0 -0
  61. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/builtin_rules/tests/only.md +0 -0
  62. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/bus.py +0 -0
  63. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/ci_adapters.py +0 -0
  64. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/ci_client.py +0 -0
  65. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/ci_federation.py +0 -0
  66. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/ci_hosts.py +0 -0
  67. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/clone.py +0 -0
  68. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/cloud_credential.py +0 -0
  69. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/cloud_login.py +0 -0
  70. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/codemap.py +0 -0
  71. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/codemap_docs.py +0 -0
  72. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/codex_hook.py +0 -0
  73. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/company_identity.py +0 -0
  74. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/company_login.py +0 -0
  75. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/config.py +0 -0
  76. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/conflicts.py +0 -0
  77. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/coordinator.py +0 -0
  78. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/cost.py +0 -0
  79. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/cost_estimate.py +0 -0
  80. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/cull.py +0 -0
  81. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/__init__.py +0 -0
  82. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/auth.py +0 -0
  83. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/events.py +0 -0
  84. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/lifecycle.py +0 -0
  85. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/peer.py +0 -0
  86. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/routes_org_permissions.py +0 -0
  87. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/schema.py +0 -0
  88. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/session_review.py +0 -0
  89. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/daemon/terminal.py +0 -0
  90. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/debuglog.py +0 -0
  91. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/demo.py +0 -0
  92. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/detect.py +0 -0
  93. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/doctor.py +0 -0
  94. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/escapes.py +0 -0
  95. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/events.py +0 -0
  96. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/gates.py +0 -0
  97. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/git.py +0 -0
  98. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/guardrails.py +0 -0
  99. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/history.py +0 -0
  100. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/identity_lock.py +0 -0
  101. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/inbox.py +0 -0
  102. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/kb.py +0 -0
  103. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/key_check.py +0 -0
  104. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/keys_cmds.py +0 -0
  105. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/keystore.py +0 -0
  106. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/knowledge.py +0 -0
  107. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/launch_health.py +0 -0
  108. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/learned_rules.py +0 -0
  109. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/learning.py +0 -0
  110. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/legacy.py +0 -0
  111. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/local_setup.py +0 -0
  112. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/login_pause.py +0 -0
  113. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/mcp_server.py +0 -0
  114. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/model_access.py +0 -0
  115. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/model_availability.py +0 -0
  116. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/native/__init__.py +0 -0
  117. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/native/catalog.py +0 -0
  118. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/native/client.py +0 -0
  119. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/native/loop.py +0 -0
  120. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/native/lsp.py +0 -0
  121. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/native/serve.py +0 -0
  122. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/native/tools.py +0 -0
  123. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/opencode.py +0 -0
  124. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/org_permissions.py +0 -0
  125. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pane_auth.py +0 -0
  126. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/picker.py +0 -0
  127. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pipeline.py +0 -0
  128. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/plugins.py +0 -0
  129. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/policy.py +0 -0
  130. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pool.py +0 -0
  131. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/preflight.py +0 -0
  132. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pricing.py +0 -0
  133. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/__init__.py +0 -0
  134. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/_files.py +0 -0
  135. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/account.py +0 -0
  136. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/audit_chain.py +0 -0
  137. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/audit_export.py +0 -0
  138. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/auth.py +0 -0
  139. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/brief_learning.py +0 -0
  140. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/cost_centers.py +0 -0
  141. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/credentials.py +0 -0
  142. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/features.py +0 -0
  143. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/keys.py +0 -0
  144. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/learning.py +0 -0
  145. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/license.py +0 -0
  146. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/loopback.py +0 -0
  147. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/managed_models.py +0 -0
  148. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/org_profiles.py +0 -0
  149. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/orgkey.py +0 -0
  150. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/rollout.py +0 -0
  151. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/route_health.py +0 -0
  152. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/settings_sync.py +0 -0
  153. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/status.py +0 -0
  154. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/team_events.py +0 -0
  155. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/pro/team_policy.py +0 -0
  156. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/procs.py +0 -0
  157. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/profiles.py +0 -0
  158. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/prompt_answer.py +0 -0
  159. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/provider_homes.py +0 -0
  160. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/providers_install.py +0 -0
  161. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/quota.py +0 -0
  162. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/repo_cmds.py +0 -0
  163. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/repos.py +0 -0
  164. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/rewind.py +0 -0
  165. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/rule_checks.py +0 -0
  166. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/savings.py +0 -0
  167. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/scratch.py +0 -0
  168. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/secrets.py +0 -0
  169. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/self_serve.py +0 -0
  170. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/service/__init__.py +0 -0
  171. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/service/errors.py +0 -0
  172. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/service/routing.py +0 -0
  173. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/service/sessions.py +0 -0
  174. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/services.py +0 -0
  175. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/sessions.py +0 -0
  176. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/sidebar_follow.py +0 -0
  177. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/sidebar_logo.py +0 -0
  178. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/signin_pause.py +0 -0
  179. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/status_cache.py +0 -0
  180. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/tasks.py +0 -0
  181. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/tmux.py +0 -0
  182. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/updates.py +0 -0
  183. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/upgrade.py +0 -0
  184. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/usage.py +0 -0
  185. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/view.py +0 -0
  186. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/wake.py +0 -0
  187. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/watch.py +0 -0
  188. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/watch_costs.py +0 -0
  189. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/web/__init__.py +0 -0
  190. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/web/chat.py +0 -0
  191. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/web/dashboard.py +0 -0
  192. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/web/diff.py +0 -0
  193. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/web/server.py +0 -0
  194. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/web/static/app.js +0 -0
  195. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/web/static/index.html +0 -0
  196. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/worker_models.py +0 -0
  197. {brindle-0.4.6 → brindle-0.5.0}/src/brindle/workspaces.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brindle
3
- Version: 0.4.6
3
+ Version: 0.5.0
4
4
  Summary: Run coding agents in parallel, each on its own git branch, with a supervisor that delegates, reviews, and merges
5
5
  Project-URL: Homepage, https://pawdelta.com/brindle/
6
6
  Project-URL: Documentation, https://pawdelta.com/brindle/docs/recommended-use
@@ -404,7 +404,7 @@ your own status line prints, so what you see doesn't change.
404
404
  | `brindle cost [--days N] [--all]` | dollar spend at list prices over the last 30 days, by model |
405
405
  | `brindle cost report [--days N] [--all]` | Pro: spend by day, profile and goal, cost per merged branch, review pass rate per worker profile |
406
406
  | `brindle history --share [--session ID]` | a few lines about this session to paste into Slack or a post: goal, milestones verified, workers, merges, reviews (and how many by a different model), parallel speedup, tokens |
407
- | `brindle permissions list / check / suggestions / accept / allow / deny / forget / reset` | the rules brindle answers workers' permission requests with, and what it suggests from your approvals (see "Permission policy") |
407
+ | `brindle permissions list / check / preset / suggestions / accept / allow / deny / forget / reset` | the rules brindle answers workers' permission requests with, the preset they started from, and what it suggests from your approvals (see "Permission policy"; saved actions are managed in the app for now, [#285](https://github.com/PawDelta/brindle/issues/285)) |
408
408
  | `brindle permissions install-codex-hook [--yes]` / `brindle permissions sync-agy` | trust brindle's Codex permission hook now (brindle does it itself when needed); copy your rules into Antigravity's settings (see "Permission policy") |
409
409
  | `brindle cost request --usd N --reason "..." [--goal TEXT]` | Enterprise (cost centers): ask an admin to approve spend over your budget. A budget refusal points here. Once approved, this month's limit (or the named goal's) goes up by the approved amount, for the month it was approved in |
410
410
  | `brindle cost requests` | Enterprise: your approval requests and their status; checks pending ones with the server (the cull pass also does, every few minutes). With cost centers, spend events also carry the repo (`owner/name`) so the org can total spend per center |
@@ -691,7 +691,7 @@ Autopilot, merge gates and cleanup:
691
691
  | `goal_audit` | `true` | once every milestone passes, an adversarial reviewer checks the work against the original goal before the goal counts as reached |
692
692
  | `merge_into` | none | branch that worker branches are cut from and merge into, whatever branch the supervisor is on |
693
693
  | `auto_merge_default_branch` | `false` | let the pipeline merge into the repo's default branch (origin HEAD, else `main`/`master`) on its own; by default it sends a "needs you" message instead, and you run `merge_workspace` yourself (manual merges are never gated) |
694
- | `permission_policy` | `"off"` | `"on"`: brindle answers Claude Code workers' permission prompts from its rules (see "Permission policy" below); off, the prompts behave as they always did |
694
+ | `permission_policy` | `"on"` with a Pro license, else `"off"` | `"on"`: brindle answers workers' permission requests from its rules (see "Permission policy" below); `"off"`: the provider's own prompts and permission mode decide, except Antigravity workers under `agy_approvals: "brindle"`, whose hook still enforces the rules. The only permission switch: a leftover `permission_essentials` key is ignored |
695
695
  | `agy_approvals` | unset | `"brindle"`: Antigravity agents run without approval prompts and brindle's hook allows or denies every call, applying the profile's `allowed_tools` (see "Antigravity" under "Permission policy"); `"prompt"`: agy asks as usual. Unset, workers get `"brindle"` and interactive agy sessions `"prompt"` |
696
696
  | `rules` | `[]` | standing rules for the supervisor, e.g. `["Fix review findings without asking", "Validate options before offering them"]`; added to every supervisor's brief. Rules in `~/.brindle/config.json`, the repo's config and `config.local.json` are all kept, so a team's rules and your own add up |
697
697
  | `plan_first` | `false` | workers propose a plan (`submit_plan`) and wait for `approve_plan` before editing |
@@ -879,26 +879,43 @@ command, path or URL; brindle never reads the screen) and brindle answers
879
879
  **allow**, **deny**, or **ask**, which leaves the prompt to you as usual. Any
880
880
  error is ask.
881
881
 
882
- The starting rules:
883
-
884
- - **allow** reading a file git tracks in the worktree or repo root (exact
885
- path, symlinks resolved and kept inside the root; never `.git/`, ignored or
886
- untracked files);
887
- - **allow** a Bash command that is exactly one of the repo's `checks`, and
888
- `git status` / `git diff` / `git log` / `git show`, but only as a single
889
- simple command: anything with `;`, `|`, `&`, `$`, backticks, quotes,
890
- redirections or globs is never auto-allowed;
891
- - **deny** `git push`, git force flags, and reading `~/.ssh`, `~/.aws`,
892
- `~/.gnupg` or `.env*`;
893
- - **ask** for everything else.
894
-
895
- A deny beats any allow; nothing else is ranked. Add your own with
896
- `brindle permissions allow|deny KIND MATCH` (kinds: `read`, `write`, `edit`,
897
- `bash`, `fetch`, `mcp`, `other`; the match is exact unless `--prefix` or
898
- `--glob`); they're kept in `~/.brindle/permissions.json`. A repo's
882
+ Nothing is built in. Every rule lives in `~/.brindle/permissions.json`, and
883
+ you can edit or remove any of them, including the ones a **preset** seeded.
884
+ Pick a preset in Settings → Permissions or at setup:
885
+
886
+ - **Autonomous** (the default): everything runs, except pushes into the
887
+ repo's default branch (ask) and destructive actions (deny: git force flags,
888
+ deleting a branch by push, a recursive `rm` of `/`, a top-level folder or
889
+ home);
890
+ - **Permissive**: edits in the worktree and everyday commands run, the rest asks;
891
+ - **Standard**: routine reads and everyday commands run, changes ask;
892
+ - **Secure**: short approvals, and a deny for anything no rule covers.
893
+
894
+ Every preset also denies reading `~/.ssh`, `~/.aws`, `~/.gnupg`, `.env*` and
895
+ the daemon's token, and asks before every push into a `release` or
896
+ `release/*` branch, which starts a signed build (an approval there is never
897
+ saved). It allows reading files git tracks, the repo's `checks`, read-only
898
+ git commands and read-only pipelines (grep, rg, ls, cat, head, `sed -n` ...
899
+ joined by pipes or `&&`, quoting read as the shell reads it). A pipeline
900
+ stops being read-only when it writes a file, substitutes a command, sets a
901
+ variable, recurses into a tree with a file a read deny covers, or reads such a
902
+ file. Precedence: a deny wins, then an ask, then an allow, then the preset's
903
+ setting for what no rule covers (ask, allow or deny). A deny or ask also
904
+ catches a part of a compound command however it's spelled (spacing, quotes,
905
+ assignments, redirects, `$(...)`, patterns the shell expands); when brindle
906
+ can't read the syntax and a deny or ask could match it, it asks.
907
+
908
+ Add your own with `brindle permissions allow|deny KIND MATCH` (kinds: `read`,
909
+ `write`, `edit`, `bash`, `fetch`, `mcp`, `other`; the match is exact unless
910
+ `--prefix` or `--glob`) or in the app, which can also make ask rules with
911
+ limits on saved approvals, timed rules and exceptions. A repo's
899
912
  `.brindle/permissions.json` (`{"rules": [...]}`, same format) can only add
900
913
  denies. `brindle permissions list` shows every rule and where it came from,
901
- `forget ID` removes one of yours, `reset` goes back to the starting rules.
914
+ `forget ID` removes one, `reset` goes back to the preset's rules. A store
915
+ written by brindle 0.4.7 is migrated on first load: its permission editor's
916
+ preset becomes Permissive, Standard or Secure (Autonomous when it chose
917
+ none), its own rules stay, and its remembered approvals become saved actions;
918
+ its old rows stay in the file.
902
919
  Profiles can add narrower, profile-local denies with a JSON array in frontmatter,
903
920
  for example `permission_denies: ["read glob ~/.private*", "bash prefix deploy"]`.
904
921
  Built-in profiles ship with no profile-specific denies by default. These denies
@@ -919,63 +936,37 @@ on without the tool running counts for nothing. Every decision is in
919
936
  `brindle history --kind permission`, and when a worker sits on a prompt, its
920
937
  supervisor is told exactly which request is pending (only you can answer it).
921
938
 
922
- **Grants.** When the app holds a Claude Code or Codex worker's request in the
923
- Inbox, you can answer **Allow for N min**. That lets this agent repeat exactly
924
- this request (the whole command, the resolved path, the https URL or the tool)
925
- in this repo until the time or the uses run out, or until you revoke it under
926
- Settings → Permission grants. A grant is spent when the hook allows the call,
927
- not when the tool succeeds (a hook can't see the result). Grants live in the
928
- daemon's memory, so a restart ends them all.
929
-
930
- Two built-in denies can also be lifted by an explicit approval. When nothing else
931
- denies the request, it is still denied at once, never held. A held request
932
- shows the CLI's own prompt, and an answer typed there would run it. The worker
933
- is told it was refused and that it asked you, and the Inbox shows the exact
934
- request with **Allow once**, **Deny**, and, when policy permits, **Always allow in this repository**. Allow it once, and the worker's next
935
- try of exactly that command uses your one-time grant. What it covers and what
936
- the Inbox shows are worked out by the daemon from the agent's own workspace,
937
- never taken from the agent. The grant expires after 15 minutes, or sooner if
938
- your org's `max_minutes` is shorter, even when the org shortens it later. It is
939
- used up even if the push then fails. If nobody answers, or the
940
- daemon isn't running, it stays denied.
941
-
942
- **Remembered approvals** are saved in your user permission preferences, across
943
- sessions and daemon restarts, until you revoke them in Settings → Permission
944
- grants. A remembered push covers the same repository, remote URL and destination
945
- branch across future commits; a file approval covers that specific file.
946
- Every use still checks the current policy, explicit denies and adapter protections.
947
- Temporary time/use limits apply to temporary grants; persistent approvals require
948
- their own policy permission. Turning that permission off prevents their use.
949
- - `git push` qualifies only as `git push <remote> <full commit sha>:refs/heads/<branch>`, run in the agent's own worktree (not another clone or a nested repository), and only when:
950
- - the remote resolves (insteadOf applied) to exactly one https, ssh or `user@host:path` URL;
951
- - none of `core.sshCommand`, `core.hooksPath`, the remote's receivepack/vcs/mirror, `push.followTags` or `push.recurseSubmodules` is set;
952
- - there is no pre-push or reference-transaction hook;
953
- - neither the repo nor your org sets protected paths (a push skips the merge check that enforces them).
954
- - `.env*` qualifies for one file inside the worktree.
955
-
956
- After your answer, brindle checks the policy, every rule and that scope again
957
- before allowing. Anything that changed meanwhile refuses it. The command then
958
- runs outside brindle.
959
-
960
- Never lifted: your own, the repo's, a profile's or your org's denies, git force
961
- flags, and reads of `~/.ssh`, `~/.aws`, `~/.gnupg` or the daemon's token.
962
- Antigravity and OpenCode workers get no grants: agy ignores a hook's allow, and
963
- OpenCode's plugin has no hold.
964
-
965
- In a Team org, only the org policy's `permission_grants` block decides what may
966
- be granted. It is read again on every request:
939
+ **Saved actions.** The app's Inbox groups pending asks by kind and general
940
+ form (a push by its destination, a file by its top folder, a command by its
941
+ first two words, an MCP tool or its server). One decision answers the group:
942
+ once, for the session, for a time, until revoked, deny, or always deny. Anything
943
+ kept is a saved action, listed and editable under Settings → Permissions. A
944
+ saved deny stops every ask it covers. A saved allow settles an ask only within
945
+ the limits of the ask rule that asked (its scope and how long approvals may
946
+ last), never past a deny rule, and never once it has expired. Every use reads
947
+ the current rules again.
948
+
949
+ Saved actions and the grouped Inbox are in the app only for now. From the
950
+ CLI, saved actions still apply to every worker, but you can't list, edit or
951
+ delete one (`brindle permissions reset` removes them all, with your own and
952
+ learned rules), and without the app a held request falls back to the worker
953
+ CLI's own prompt in its pane, one exact request at a time. CLI commands for
954
+ both are tracked in
955
+ [#285](https://github.com/PawDelta/brindle/issues/285).
956
+
957
+ In a Team org, the org policy's `permission_grants` block bounds what a saved
958
+ allow may do. It is read again on every request:
967
959
 
968
960
  ```json
969
- "permission_grants": {"allow": true, "kinds": ["bash", "fetch"], "overridable": ["git-push"],
970
- "max_minutes": 30, "max_uses": 5, "allow_persistent": true,
971
- "deny": ["bash prefix terraform apply"]}
961
+ "permission_grants": {"allow": true, "kinds": ["bash", "fetch"], "max_minutes": 30,
962
+ "allow_persistent": true, "lifetimes": ["session", "time", "forever"],
963
+ "scopes": ["branch", "remote"], "deny": ["bash prefix terraform apply"]}
972
964
  ```
973
965
 
974
966
  - `deny` entries are enforced for every provider and can't be lifted.
975
- - `allow_persistent` permits remembered overrides of these two built-in denies; omitted or false allows only temporary overrides. This setting does not control ordinary saved allow rules. The admin policy editor is not delivered by this local engine change.
976
- - A policy without the block, an unknown or malformed field (which makes the whole policy unusable), a policy that can't be read, or a paused or shut-down member: no grants.
977
- - Without a Team org, any kind can be granted, for up to 60 min and 20 uses. Both built-in denies support one-time or remembered approvals.
978
- - The org backend that serves this block isn't part of this repository. Until it serves one, Team orgs get no grants. It is enforced from the cached policy, or in air-gap mode from `.brindle/policy.json`.
967
+ - A saved allow applies only for the listed `kinds`, `lifetimes` and `scopes`, with timed ones capped at `max_minutes`; one that lasts until revoked also needs `allow_persistent`.
968
+ - A policy without the block, one that can't be read, or a paused or shut-down member: no saved allow applies.
969
+ - Org admins edit the block in Settings → Organization approvals. It is enforced from the cached policy, or in air-gap mode from `.brindle/policy.json`.
979
970
 
980
971
  **Codex.** Codex runs a hook only once it's trusted, so with
981
972
  `permission_policy` on, brindle trusts its own hook the first time a Codex worker
@@ -372,7 +372,7 @@ your own status line prints, so what you see doesn't change.
372
372
  | `brindle cost [--days N] [--all]` | dollar spend at list prices over the last 30 days, by model |
373
373
  | `brindle cost report [--days N] [--all]` | Pro: spend by day, profile and goal, cost per merged branch, review pass rate per worker profile |
374
374
  | `brindle history --share [--session ID]` | a few lines about this session to paste into Slack or a post: goal, milestones verified, workers, merges, reviews (and how many by a different model), parallel speedup, tokens |
375
- | `brindle permissions list / check / suggestions / accept / allow / deny / forget / reset` | the rules brindle answers workers' permission requests with, and what it suggests from your approvals (see "Permission policy") |
375
+ | `brindle permissions list / check / preset / suggestions / accept / allow / deny / forget / reset` | the rules brindle answers workers' permission requests with, the preset they started from, and what it suggests from your approvals (see "Permission policy"; saved actions are managed in the app for now, [#285](https://github.com/PawDelta/brindle/issues/285)) |
376
376
  | `brindle permissions install-codex-hook [--yes]` / `brindle permissions sync-agy` | trust brindle's Codex permission hook now (brindle does it itself when needed); copy your rules into Antigravity's settings (see "Permission policy") |
377
377
  | `brindle cost request --usd N --reason "..." [--goal TEXT]` | Enterprise (cost centers): ask an admin to approve spend over your budget. A budget refusal points here. Once approved, this month's limit (or the named goal's) goes up by the approved amount, for the month it was approved in |
378
378
  | `brindle cost requests` | Enterprise: your approval requests and their status; checks pending ones with the server (the cull pass also does, every few minutes). With cost centers, spend events also carry the repo (`owner/name`) so the org can total spend per center |
@@ -659,7 +659,7 @@ Autopilot, merge gates and cleanup:
659
659
  | `goal_audit` | `true` | once every milestone passes, an adversarial reviewer checks the work against the original goal before the goal counts as reached |
660
660
  | `merge_into` | none | branch that worker branches are cut from and merge into, whatever branch the supervisor is on |
661
661
  | `auto_merge_default_branch` | `false` | let the pipeline merge into the repo's default branch (origin HEAD, else `main`/`master`) on its own; by default it sends a "needs you" message instead, and you run `merge_workspace` yourself (manual merges are never gated) |
662
- | `permission_policy` | `"off"` | `"on"`: brindle answers Claude Code workers' permission prompts from its rules (see "Permission policy" below); off, the prompts behave as they always did |
662
+ | `permission_policy` | `"on"` with a Pro license, else `"off"` | `"on"`: brindle answers workers' permission requests from its rules (see "Permission policy" below); `"off"`: the provider's own prompts and permission mode decide, except Antigravity workers under `agy_approvals: "brindle"`, whose hook still enforces the rules. The only permission switch: a leftover `permission_essentials` key is ignored |
663
663
  | `agy_approvals` | unset | `"brindle"`: Antigravity agents run without approval prompts and brindle's hook allows or denies every call, applying the profile's `allowed_tools` (see "Antigravity" under "Permission policy"); `"prompt"`: agy asks as usual. Unset, workers get `"brindle"` and interactive agy sessions `"prompt"` |
664
664
  | `rules` | `[]` | standing rules for the supervisor, e.g. `["Fix review findings without asking", "Validate options before offering them"]`; added to every supervisor's brief. Rules in `~/.brindle/config.json`, the repo's config and `config.local.json` are all kept, so a team's rules and your own add up |
665
665
  | `plan_first` | `false` | workers propose a plan (`submit_plan`) and wait for `approve_plan` before editing |
@@ -847,26 +847,43 @@ command, path or URL; brindle never reads the screen) and brindle answers
847
847
  **allow**, **deny**, or **ask**, which leaves the prompt to you as usual. Any
848
848
  error is ask.
849
849
 
850
- The starting rules:
851
-
852
- - **allow** reading a file git tracks in the worktree or repo root (exact
853
- path, symlinks resolved and kept inside the root; never `.git/`, ignored or
854
- untracked files);
855
- - **allow** a Bash command that is exactly one of the repo's `checks`, and
856
- `git status` / `git diff` / `git log` / `git show`, but only as a single
857
- simple command: anything with `;`, `|`, `&`, `$`, backticks, quotes,
858
- redirections or globs is never auto-allowed;
859
- - **deny** `git push`, git force flags, and reading `~/.ssh`, `~/.aws`,
860
- `~/.gnupg` or `.env*`;
861
- - **ask** for everything else.
862
-
863
- A deny beats any allow; nothing else is ranked. Add your own with
864
- `brindle permissions allow|deny KIND MATCH` (kinds: `read`, `write`, `edit`,
865
- `bash`, `fetch`, `mcp`, `other`; the match is exact unless `--prefix` or
866
- `--glob`); they're kept in `~/.brindle/permissions.json`. A repo's
850
+ Nothing is built in. Every rule lives in `~/.brindle/permissions.json`, and
851
+ you can edit or remove any of them, including the ones a **preset** seeded.
852
+ Pick a preset in Settings → Permissions or at setup:
853
+
854
+ - **Autonomous** (the default): everything runs, except pushes into the
855
+ repo's default branch (ask) and destructive actions (deny: git force flags,
856
+ deleting a branch by push, a recursive `rm` of `/`, a top-level folder or
857
+ home);
858
+ - **Permissive**: edits in the worktree and everyday commands run, the rest asks;
859
+ - **Standard**: routine reads and everyday commands run, changes ask;
860
+ - **Secure**: short approvals, and a deny for anything no rule covers.
861
+
862
+ Every preset also denies reading `~/.ssh`, `~/.aws`, `~/.gnupg`, `.env*` and
863
+ the daemon's token, and asks before every push into a `release` or
864
+ `release/*` branch, which starts a signed build (an approval there is never
865
+ saved). It allows reading files git tracks, the repo's `checks`, read-only
866
+ git commands and read-only pipelines (grep, rg, ls, cat, head, `sed -n` ...
867
+ joined by pipes or `&&`, quoting read as the shell reads it). A pipeline
868
+ stops being read-only when it writes a file, substitutes a command, sets a
869
+ variable, recurses into a tree with a file a read deny covers, or reads such a
870
+ file. Precedence: a deny wins, then an ask, then an allow, then the preset's
871
+ setting for what no rule covers (ask, allow or deny). A deny or ask also
872
+ catches a part of a compound command however it's spelled (spacing, quotes,
873
+ assignments, redirects, `$(...)`, patterns the shell expands); when brindle
874
+ can't read the syntax and a deny or ask could match it, it asks.
875
+
876
+ Add your own with `brindle permissions allow|deny KIND MATCH` (kinds: `read`,
877
+ `write`, `edit`, `bash`, `fetch`, `mcp`, `other`; the match is exact unless
878
+ `--prefix` or `--glob`) or in the app, which can also make ask rules with
879
+ limits on saved approvals, timed rules and exceptions. A repo's
867
880
  `.brindle/permissions.json` (`{"rules": [...]}`, same format) can only add
868
881
  denies. `brindle permissions list` shows every rule and where it came from,
869
- `forget ID` removes one of yours, `reset` goes back to the starting rules.
882
+ `forget ID` removes one, `reset` goes back to the preset's rules. A store
883
+ written by brindle 0.4.7 is migrated on first load: its permission editor's
884
+ preset becomes Permissive, Standard or Secure (Autonomous when it chose
885
+ none), its own rules stay, and its remembered approvals become saved actions;
886
+ its old rows stay in the file.
870
887
  Profiles can add narrower, profile-local denies with a JSON array in frontmatter,
871
888
  for example `permission_denies: ["read glob ~/.private*", "bash prefix deploy"]`.
872
889
  Built-in profiles ship with no profile-specific denies by default. These denies
@@ -887,63 +904,37 @@ on without the tool running counts for nothing. Every decision is in
887
904
  `brindle history --kind permission`, and when a worker sits on a prompt, its
888
905
  supervisor is told exactly which request is pending (only you can answer it).
889
906
 
890
- **Grants.** When the app holds a Claude Code or Codex worker's request in the
891
- Inbox, you can answer **Allow for N min**. That lets this agent repeat exactly
892
- this request (the whole command, the resolved path, the https URL or the tool)
893
- in this repo until the time or the uses run out, or until you revoke it under
894
- Settings → Permission grants. A grant is spent when the hook allows the call,
895
- not when the tool succeeds (a hook can't see the result). Grants live in the
896
- daemon's memory, so a restart ends them all.
897
-
898
- Two built-in denies can also be lifted by an explicit approval. When nothing else
899
- denies the request, it is still denied at once, never held. A held request
900
- shows the CLI's own prompt, and an answer typed there would run it. The worker
901
- is told it was refused and that it asked you, and the Inbox shows the exact
902
- request with **Allow once**, **Deny**, and, when policy permits, **Always allow in this repository**. Allow it once, and the worker's next
903
- try of exactly that command uses your one-time grant. What it covers and what
904
- the Inbox shows are worked out by the daemon from the agent's own workspace,
905
- never taken from the agent. The grant expires after 15 minutes, or sooner if
906
- your org's `max_minutes` is shorter, even when the org shortens it later. It is
907
- used up even if the push then fails. If nobody answers, or the
908
- daemon isn't running, it stays denied.
909
-
910
- **Remembered approvals** are saved in your user permission preferences, across
911
- sessions and daemon restarts, until you revoke them in Settings → Permission
912
- grants. A remembered push covers the same repository, remote URL and destination
913
- branch across future commits; a file approval covers that specific file.
914
- Every use still checks the current policy, explicit denies and adapter protections.
915
- Temporary time/use limits apply to temporary grants; persistent approvals require
916
- their own policy permission. Turning that permission off prevents their use.
917
- - `git push` qualifies only as `git push <remote> <full commit sha>:refs/heads/<branch>`, run in the agent's own worktree (not another clone or a nested repository), and only when:
918
- - the remote resolves (insteadOf applied) to exactly one https, ssh or `user@host:path` URL;
919
- - none of `core.sshCommand`, `core.hooksPath`, the remote's receivepack/vcs/mirror, `push.followTags` or `push.recurseSubmodules` is set;
920
- - there is no pre-push or reference-transaction hook;
921
- - neither the repo nor your org sets protected paths (a push skips the merge check that enforces them).
922
- - `.env*` qualifies for one file inside the worktree.
923
-
924
- After your answer, brindle checks the policy, every rule and that scope again
925
- before allowing. Anything that changed meanwhile refuses it. The command then
926
- runs outside brindle.
927
-
928
- Never lifted: your own, the repo's, a profile's or your org's denies, git force
929
- flags, and reads of `~/.ssh`, `~/.aws`, `~/.gnupg` or the daemon's token.
930
- Antigravity and OpenCode workers get no grants: agy ignores a hook's allow, and
931
- OpenCode's plugin has no hold.
932
-
933
- In a Team org, only the org policy's `permission_grants` block decides what may
934
- be granted. It is read again on every request:
907
+ **Saved actions.** The app's Inbox groups pending asks by kind and general
908
+ form (a push by its destination, a file by its top folder, a command by its
909
+ first two words, an MCP tool or its server). One decision answers the group:
910
+ once, for the session, for a time, until revoked, deny, or always deny. Anything
911
+ kept is a saved action, listed and editable under Settings → Permissions. A
912
+ saved deny stops every ask it covers. A saved allow settles an ask only within
913
+ the limits of the ask rule that asked (its scope and how long approvals may
914
+ last), never past a deny rule, and never once it has expired. Every use reads
915
+ the current rules again.
916
+
917
+ Saved actions and the grouped Inbox are in the app only for now. From the
918
+ CLI, saved actions still apply to every worker, but you can't list, edit or
919
+ delete one (`brindle permissions reset` removes them all, with your own and
920
+ learned rules), and without the app a held request falls back to the worker
921
+ CLI's own prompt in its pane, one exact request at a time. CLI commands for
922
+ both are tracked in
923
+ [#285](https://github.com/PawDelta/brindle/issues/285).
924
+
925
+ In a Team org, the org policy's `permission_grants` block bounds what a saved
926
+ allow may do. It is read again on every request:
935
927
 
936
928
  ```json
937
- "permission_grants": {"allow": true, "kinds": ["bash", "fetch"], "overridable": ["git-push"],
938
- "max_minutes": 30, "max_uses": 5, "allow_persistent": true,
939
- "deny": ["bash prefix terraform apply"]}
929
+ "permission_grants": {"allow": true, "kinds": ["bash", "fetch"], "max_minutes": 30,
930
+ "allow_persistent": true, "lifetimes": ["session", "time", "forever"],
931
+ "scopes": ["branch", "remote"], "deny": ["bash prefix terraform apply"]}
940
932
  ```
941
933
 
942
934
  - `deny` entries are enforced for every provider and can't be lifted.
943
- - `allow_persistent` permits remembered overrides of these two built-in denies; omitted or false allows only temporary overrides. This setting does not control ordinary saved allow rules. The admin policy editor is not delivered by this local engine change.
944
- - A policy without the block, an unknown or malformed field (which makes the whole policy unusable), a policy that can't be read, or a paused or shut-down member: no grants.
945
- - Without a Team org, any kind can be granted, for up to 60 min and 20 uses. Both built-in denies support one-time or remembered approvals.
946
- - The org backend that serves this block isn't part of this repository. Until it serves one, Team orgs get no grants. It is enforced from the cached policy, or in air-gap mode from `.brindle/policy.json`.
935
+ - A saved allow applies only for the listed `kinds`, `lifetimes` and `scopes`, with timed ones capped at `max_minutes`; one that lasts until revoked also needs `allow_persistent`.
936
+ - A policy without the block, one that can't be read, or a paused or shut-down member: no saved allow applies.
937
+ - Org admins edit the block in Settings → Organization approvals. It is enforced from the cached policy, or in air-gap mode from `.brindle/policy.json`.
947
938
 
948
939
  **Codex.** Codex runs a hook only once it's trusted, so with
949
940
  `permission_policy` on, brindle trusts its own hook the first time a Codex worker
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "brindle"
3
- version = "0.4.6"
3
+ version = "0.5.0"
4
4
  description = "Run coding agents in parallel, each on its own git branch, with a supervisor that delegates, reviews, and merges"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"