brindle 0.3.2__tar.gz → 0.3.3__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.
- {brindle-0.3.2 → brindle-0.3.3}/PKG-INFO +96 -2
- {brindle-0.3.2 → brindle-0.3.3}/README.md +95 -1
- {brindle-0.3.2 → brindle-0.3.3}/pyproject.toml +1 -1
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/agents.py +184 -44
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/autopilot.py +13 -1
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/ci_client.py +2 -3
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/cli.py +34 -5
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/codex_hook.py +22 -4
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/config.py +5 -1
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/db.py +18 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/doctor.py +24 -0
- brindle-0.3.3/src/brindle/launch_health.py +379 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/model_access.py +34 -11
- brindle-0.3.3/src/brindle/model_availability.py +504 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/native/runner.py +2 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/permissions.py +7 -5
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/providers.py +98 -14
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/tmux.py +22 -0
- {brindle-0.3.2 → brindle-0.3.3}/.gitignore +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/LICENSE +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/SCHEDULE-A +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/__init__.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/__main__.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/account.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/airgap.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/antigravity.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/budget.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/__init__.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/backend-auditor.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/developer-codex.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/developer-heavy.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/developer-light.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/developer-local.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/developer.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/qa.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/reviewer-codex.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/reviewer-local.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/reviewer.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/subagent.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_agents/supervisor.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_rules/__init__.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_rules/security/backend.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_rules/style/minimal-diff.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/builtin_rules/tests/only.md +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/ci_adapters.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/ci_federation.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/ci_hosts.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/codemap.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/company_identity.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/company_login.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/conflicts.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/cost.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/cost_estimate.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/cull.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/demo.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/detect.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/escapes.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/events.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/gates.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/git.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/guardrails.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/history.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/identity_lock.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/inbox.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/keys_cmds.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/keystore.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/learned_rules.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/learning.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/legacy.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/mcp_server.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/native/__init__.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/native/client.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/native/loop.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/native/permissions.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/native/serve.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/native/tools.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pane_auth.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pipeline.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/plugins.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/policy.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pool.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pricing.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/__init__.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/_files.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/account.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/audit_chain.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/audit_export.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/auth.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/brief_learning.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/cost_centers.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/credentials.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/features.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/keys.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/learning.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/license.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/loopback.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/managed_models.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/org_profiles.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/orgkey.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/rollout.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/settings_sync.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/status.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/team_events.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/pro/team_policy.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/procs.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/profiles.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/quota.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/repo_cmds.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/repos.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/rewind.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/rule_checks.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/savings.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/scratch.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/secrets.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/self_serve.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/services.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/sessions.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/sidebar_follow.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/signin_pause.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/status_cache.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/tasks.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/usage.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/view.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/watch.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/watch_costs.py +0 -0
- {brindle-0.3.2 → brindle-0.3.3}/src/brindle/workspaces.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: brindle
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
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
|
|
@@ -89,7 +89,7 @@ uv tool install --editable ~/Projects/brindle # or from a local checkout
|
|
|
89
89
|
brindle drives Claude Code, so you need that too (`npm install -g @anthropic-ai/claude-code`).
|
|
90
90
|
|
|
91
91
|
`brindle --version` prints the installed version; the tmux status bar of every brindle
|
|
92
|
-
session shows it too (`brindle 0.3.
|
|
92
|
+
session shows it too (`brindle 0.3.3`). A session started before an upgrade keeps
|
|
93
93
|
running the old code, and shows the old number, until you restart it.
|
|
94
94
|
|
|
95
95
|
## Quick start
|
|
@@ -603,6 +603,21 @@ keep theirs):
|
|
|
603
603
|
No tier prefers another provider for its own sake: all-Claude or all-Codex may
|
|
604
604
|
be what works best for you, and that's for the learner to find out.
|
|
605
605
|
|
|
606
|
+
Routing merges per tier in this order: built-in defaults, `~/.brindle/config.json`
|
|
607
|
+
(every repo), the repo's `.brindle/config.json` (shared with the team), then
|
|
608
|
+
`.brindle/config.local.json` (your override for that repo). Each tier you set
|
|
609
|
+
replaces that tier's list; tiers you leave out keep the list from the layer below.
|
|
610
|
+
For example, put this in `~/.brindle/config.json` to use Codex for light tasks
|
|
611
|
+
in every repo, or in a repo's `.brindle/config.local.json` to do so only there:
|
|
612
|
+
|
|
613
|
+
```json
|
|
614
|
+
{"routing": {"light": ["developer-codex", "developer"]}}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
Run `brindle doctor` in the repo to see the effective list and source file for
|
|
618
|
+
each tier. Unknown profile names are skipped; doctor and the routing reply
|
|
619
|
+
report the missing name and the file that supplied it.
|
|
620
|
+
|
|
606
621
|
`developer-light` runs on Claude Haiku at low effort; `developer` on your Claude
|
|
607
622
|
Code default model; `developer-codex` on Codex; `developer-heavy` on Claude Fable
|
|
608
623
|
at high effort.
|
|
@@ -613,6 +628,53 @@ wins. When every candidate is out, the repo's `default_agent` runs. The reply sa
|
|
|
613
628
|
what was picked and why, e.g. `weight medium -> developer (Codex at 93%, skipped developer-codex)`.
|
|
614
629
|
An `agent_profile` you pass, or a milestone's `profile`, always wins over weight.
|
|
615
630
|
|
|
631
|
+
Provisioning and routing also check explicit models against supported read-only
|
|
632
|
+
catalogs, with the managed model, stored keys and the worker's filtered pane
|
|
633
|
+
environment. A model absent from a complete authoritative catalog is rejected
|
|
634
|
+
before creating a worker worktree or process. Partial catalogs, aliases,
|
|
635
|
+
discovery errors and Codex's bundled catalogs remain unverified; being listed
|
|
636
|
+
does not prove generation access, billing or quota. Catalog discovery is bounded
|
|
637
|
+
to five seconds for standalone checks; foreground routing/provisioning limits
|
|
638
|
+
discovery to one second, leaving room in the three-second launch budget for
|
|
639
|
+
provisioning and bounded helper cleanup. A timeout remains unverified and
|
|
640
|
+
launch proceeds with the real-task health follow-up. Catalogs are cached
|
|
641
|
+
briefly by environment and local account/config
|
|
642
|
+
revision where available. Routing and provisioning reuse equivalent catalog
|
|
643
|
+
context across worktrees, excluding launch bookkeeping while retaining project
|
|
644
|
+
settings, credentials and account selectors. CLI catalogs remain advisory;
|
|
645
|
+
unobservable external/keychain login changes may remain cached for 30 seconds.
|
|
646
|
+
Custom CLI binaries retain separate cache entries per working directory.
|
|
647
|
+
Claude, Bedrock, Vertex and Foundry have no catalog
|
|
648
|
+
probe here; no Claude CLI or synthetic generation request is used for these checks.
|
|
649
|
+
|
|
650
|
+
The real first worker task is sent once. A detached helper inspects its current
|
|
651
|
+
pane five seconds after delivery, so readiness delays do not use up that window.
|
|
652
|
+
Fresh interactive Antigravity chats without a task still receive their profile,
|
|
653
|
+
tool instructions and any autopilot context once after readiness; worker
|
|
654
|
+
instructions accompany the actual task in the same delivery.
|
|
655
|
+
For argv tasks, the timer starts at prompt submission or observed CLI readiness,
|
|
656
|
+
after trust/startup handling; readiness timeout does not establish delivery or
|
|
657
|
+
release queued work. Paused workers, replaced launches and reassigned panes are
|
|
658
|
+
excluded from the observation.
|
|
659
|
+
Explicit fresh authentication, access, model and capacity errors, or an early
|
|
660
|
+
exit, produce a safe supervisor message with a next step. A live process with
|
|
661
|
+
no clear result is recorded as pending for diagnostics, not verified model
|
|
662
|
+
access; it does not send a supervisor notification. Refusals use
|
|
663
|
+
the existing one-hour cooldown, scoped to the effective model/environment and
|
|
664
|
+
local login revision. Changing the account, model or credentials invalidates
|
|
665
|
+
that refusal; CLI/keychain account changes without an observable local revision
|
|
666
|
+
may require waiting for the cooldown or clearing `model_refusals.json`.
|
|
667
|
+
This is a single observation, not an entitlement test: unfamiliar error layouts,
|
|
668
|
+
later failures and slow requests can remain pending. It does not scan
|
|
669
|
+
historical transcripts, and excludes task text, previous pane lines and older
|
|
670
|
+
marked replies, fenced examples and ordinary assistant/tool explanations. A
|
|
671
|
+
Codex follow-up retains the complete submitted argv prompt (including profile
|
|
672
|
+
instructions) and distinguishes assistant/tool responses from the idle composer.
|
|
673
|
+
Quoted prompts and error-looking markers inside assistant/tool output remain
|
|
674
|
+
ambiguous and pending; markers from another provider do not establish failure.
|
|
675
|
+
A separate detached check covers headless and argv startup exits before task
|
|
676
|
+
delivery. Existing readiness and watch/cull handling continues afterward.
|
|
677
|
+
|
|
616
678
|
**Hosted learning (brindle Pro).** With a plan that includes it, brindle learns
|
|
617
679
|
which of your `learning_candidates` profiles suits which kind of task, and picks
|
|
618
680
|
one when `assign` gets no profile and no milestone names one (the reply says
|
|
@@ -711,6 +773,38 @@ Codex patches are checked file by file: allowed only if every file is. Codex
|
|
|
711
773
|
doesn't say which tool run followed which prompt, so brindle doesn't learn from
|
|
712
774
|
Codex approvals. To undo, delete that entry (or untrust it in Codex's `/hooks`).
|
|
713
775
|
|
|
776
|
+
Codex also uses the profile's `allowed_tools` shell entries: `Bash(just lint)`
|
|
777
|
+
allows that exact command, and `Bash(task test:*)` allows it with arguments.
|
|
778
|
+
The same simple-command restriction applies, and default, user, repo and
|
|
779
|
+
profile denies still win. Other `allowed_tools` entries aren't translated.
|
|
780
|
+
An unrecognized patch header prevents automatic approval without discarding
|
|
781
|
+
denies for files brindle can identify. Session/status bookkeeping failures
|
|
782
|
+
don't discard the hook's decision; failures to evaluate the policy leave
|
|
783
|
+
Codex's normal approval flow in place.
|
|
784
|
+
|
|
785
|
+
Scope and platform limits: this is an **approval-request hook**, not a gate
|
|
786
|
+
on every tool call. Codex commands already permitted by its sandbox or own
|
|
787
|
+
rules never reach it, so brindle cannot enforce denies on those calls. It
|
|
788
|
+
doesn't change Codex's sandbox or approval mode, and cannot make a `never`
|
|
789
|
+
approval mode interactive. Disabled hooks, managed-only hook policies, older
|
|
790
|
+
Codex versions without `PermissionRequest`, and nonlocal execution can prevent
|
|
791
|
+
the hook from running. Keep Codex's own restrictions for tools that must always
|
|
792
|
+
be blocked. See the [OpenAI hook protocol](https://learn.chatgpt.com/docs/hooks).
|
|
793
|
+
|
|
794
|
+
The integration targets local macOS/Linux Codex CLI processes (POSIX shell
|
|
795
|
+
quoting); native Windows hook commands aren't supported. The local app-server
|
|
796
|
+
protocol was checked on macOS with Codex CLI **0.162.1**: newline-delimited
|
|
797
|
+
`initialize`, `initialized`, and `hooks/list` returned the session-flags key
|
|
798
|
+
above, `eventName: "permissionRequest"`, `source: "sessionFlags"`,
|
|
799
|
+
`currentHash`, `enabled: true`, and `trustStatus: "trusted"` for the installed
|
|
800
|
+
brindle hook. This read-only probe made no model calls or trust edits; hook
|
|
801
|
+
dispatch/allow/deny behavior is covered by the permission tests. Linux runtime
|
|
802
|
+
and native Windows behavior were not exercised by that probe.
|
|
803
|
+
`codex features list` also reported `hooks stable true` without a user
|
|
804
|
+
`features.hooks` setting, both on 0.162.1 and the bundled 0.158.0-alpha.2.1.
|
|
805
|
+
A session override of `features.hooks=false` reported false. No feature-enable
|
|
806
|
+
flag is needed on these versions, and brindle leaves explicit disablement alone.
|
|
807
|
+
|
|
714
808
|
**Antigravity.** agy's hook can deny but its "allow" is ignored (an agy bug),
|
|
715
809
|
and it has no "no opinion" answer. So the hook denies what the policy denies,
|
|
716
810
|
answers "allow" for a file inside the workspace (which agy reads and writes
|
|
@@ -59,7 +59,7 @@ uv tool install --editable ~/Projects/brindle # or from a local checkout
|
|
|
59
59
|
brindle drives Claude Code, so you need that too (`npm install -g @anthropic-ai/claude-code`).
|
|
60
60
|
|
|
61
61
|
`brindle --version` prints the installed version; the tmux status bar of every brindle
|
|
62
|
-
session shows it too (`brindle 0.3.
|
|
62
|
+
session shows it too (`brindle 0.3.3`). A session started before an upgrade keeps
|
|
63
63
|
running the old code, and shows the old number, until you restart it.
|
|
64
64
|
|
|
65
65
|
## Quick start
|
|
@@ -573,6 +573,21 @@ keep theirs):
|
|
|
573
573
|
No tier prefers another provider for its own sake: all-Claude or all-Codex may
|
|
574
574
|
be what works best for you, and that's for the learner to find out.
|
|
575
575
|
|
|
576
|
+
Routing merges per tier in this order: built-in defaults, `~/.brindle/config.json`
|
|
577
|
+
(every repo), the repo's `.brindle/config.json` (shared with the team), then
|
|
578
|
+
`.brindle/config.local.json` (your override for that repo). Each tier you set
|
|
579
|
+
replaces that tier's list; tiers you leave out keep the list from the layer below.
|
|
580
|
+
For example, put this in `~/.brindle/config.json` to use Codex for light tasks
|
|
581
|
+
in every repo, or in a repo's `.brindle/config.local.json` to do so only there:
|
|
582
|
+
|
|
583
|
+
```json
|
|
584
|
+
{"routing": {"light": ["developer-codex", "developer"]}}
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
Run `brindle doctor` in the repo to see the effective list and source file for
|
|
588
|
+
each tier. Unknown profile names are skipped; doctor and the routing reply
|
|
589
|
+
report the missing name and the file that supplied it.
|
|
590
|
+
|
|
576
591
|
`developer-light` runs on Claude Haiku at low effort; `developer` on your Claude
|
|
577
592
|
Code default model; `developer-codex` on Codex; `developer-heavy` on Claude Fable
|
|
578
593
|
at high effort.
|
|
@@ -583,6 +598,53 @@ wins. When every candidate is out, the repo's `default_agent` runs. The reply sa
|
|
|
583
598
|
what was picked and why, e.g. `weight medium -> developer (Codex at 93%, skipped developer-codex)`.
|
|
584
599
|
An `agent_profile` you pass, or a milestone's `profile`, always wins over weight.
|
|
585
600
|
|
|
601
|
+
Provisioning and routing also check explicit models against supported read-only
|
|
602
|
+
catalogs, with the managed model, stored keys and the worker's filtered pane
|
|
603
|
+
environment. A model absent from a complete authoritative catalog is rejected
|
|
604
|
+
before creating a worker worktree or process. Partial catalogs, aliases,
|
|
605
|
+
discovery errors and Codex's bundled catalogs remain unverified; being listed
|
|
606
|
+
does not prove generation access, billing or quota. Catalog discovery is bounded
|
|
607
|
+
to five seconds for standalone checks; foreground routing/provisioning limits
|
|
608
|
+
discovery to one second, leaving room in the three-second launch budget for
|
|
609
|
+
provisioning and bounded helper cleanup. A timeout remains unverified and
|
|
610
|
+
launch proceeds with the real-task health follow-up. Catalogs are cached
|
|
611
|
+
briefly by environment and local account/config
|
|
612
|
+
revision where available. Routing and provisioning reuse equivalent catalog
|
|
613
|
+
context across worktrees, excluding launch bookkeeping while retaining project
|
|
614
|
+
settings, credentials and account selectors. CLI catalogs remain advisory;
|
|
615
|
+
unobservable external/keychain login changes may remain cached for 30 seconds.
|
|
616
|
+
Custom CLI binaries retain separate cache entries per working directory.
|
|
617
|
+
Claude, Bedrock, Vertex and Foundry have no catalog
|
|
618
|
+
probe here; no Claude CLI or synthetic generation request is used for these checks.
|
|
619
|
+
|
|
620
|
+
The real first worker task is sent once. A detached helper inspects its current
|
|
621
|
+
pane five seconds after delivery, so readiness delays do not use up that window.
|
|
622
|
+
Fresh interactive Antigravity chats without a task still receive their profile,
|
|
623
|
+
tool instructions and any autopilot context once after readiness; worker
|
|
624
|
+
instructions accompany the actual task in the same delivery.
|
|
625
|
+
For argv tasks, the timer starts at prompt submission or observed CLI readiness,
|
|
626
|
+
after trust/startup handling; readiness timeout does not establish delivery or
|
|
627
|
+
release queued work. Paused workers, replaced launches and reassigned panes are
|
|
628
|
+
excluded from the observation.
|
|
629
|
+
Explicit fresh authentication, access, model and capacity errors, or an early
|
|
630
|
+
exit, produce a safe supervisor message with a next step. A live process with
|
|
631
|
+
no clear result is recorded as pending for diagnostics, not verified model
|
|
632
|
+
access; it does not send a supervisor notification. Refusals use
|
|
633
|
+
the existing one-hour cooldown, scoped to the effective model/environment and
|
|
634
|
+
local login revision. Changing the account, model or credentials invalidates
|
|
635
|
+
that refusal; CLI/keychain account changes without an observable local revision
|
|
636
|
+
may require waiting for the cooldown or clearing `model_refusals.json`.
|
|
637
|
+
This is a single observation, not an entitlement test: unfamiliar error layouts,
|
|
638
|
+
later failures and slow requests can remain pending. It does not scan
|
|
639
|
+
historical transcripts, and excludes task text, previous pane lines and older
|
|
640
|
+
marked replies, fenced examples and ordinary assistant/tool explanations. A
|
|
641
|
+
Codex follow-up retains the complete submitted argv prompt (including profile
|
|
642
|
+
instructions) and distinguishes assistant/tool responses from the idle composer.
|
|
643
|
+
Quoted prompts and error-looking markers inside assistant/tool output remain
|
|
644
|
+
ambiguous and pending; markers from another provider do not establish failure.
|
|
645
|
+
A separate detached check covers headless and argv startup exits before task
|
|
646
|
+
delivery. Existing readiness and watch/cull handling continues afterward.
|
|
647
|
+
|
|
586
648
|
**Hosted learning (brindle Pro).** With a plan that includes it, brindle learns
|
|
587
649
|
which of your `learning_candidates` profiles suits which kind of task, and picks
|
|
588
650
|
one when `assign` gets no profile and no milestone names one (the reply says
|
|
@@ -681,6 +743,38 @@ Codex patches are checked file by file: allowed only if every file is. Codex
|
|
|
681
743
|
doesn't say which tool run followed which prompt, so brindle doesn't learn from
|
|
682
744
|
Codex approvals. To undo, delete that entry (or untrust it in Codex's `/hooks`).
|
|
683
745
|
|
|
746
|
+
Codex also uses the profile's `allowed_tools` shell entries: `Bash(just lint)`
|
|
747
|
+
allows that exact command, and `Bash(task test:*)` allows it with arguments.
|
|
748
|
+
The same simple-command restriction applies, and default, user, repo and
|
|
749
|
+
profile denies still win. Other `allowed_tools` entries aren't translated.
|
|
750
|
+
An unrecognized patch header prevents automatic approval without discarding
|
|
751
|
+
denies for files brindle can identify. Session/status bookkeeping failures
|
|
752
|
+
don't discard the hook's decision; failures to evaluate the policy leave
|
|
753
|
+
Codex's normal approval flow in place.
|
|
754
|
+
|
|
755
|
+
Scope and platform limits: this is an **approval-request hook**, not a gate
|
|
756
|
+
on every tool call. Codex commands already permitted by its sandbox or own
|
|
757
|
+
rules never reach it, so brindle cannot enforce denies on those calls. It
|
|
758
|
+
doesn't change Codex's sandbox or approval mode, and cannot make a `never`
|
|
759
|
+
approval mode interactive. Disabled hooks, managed-only hook policies, older
|
|
760
|
+
Codex versions without `PermissionRequest`, and nonlocal execution can prevent
|
|
761
|
+
the hook from running. Keep Codex's own restrictions for tools that must always
|
|
762
|
+
be blocked. See the [OpenAI hook protocol](https://learn.chatgpt.com/docs/hooks).
|
|
763
|
+
|
|
764
|
+
The integration targets local macOS/Linux Codex CLI processes (POSIX shell
|
|
765
|
+
quoting); native Windows hook commands aren't supported. The local app-server
|
|
766
|
+
protocol was checked on macOS with Codex CLI **0.162.1**: newline-delimited
|
|
767
|
+
`initialize`, `initialized`, and `hooks/list` returned the session-flags key
|
|
768
|
+
above, `eventName: "permissionRequest"`, `source: "sessionFlags"`,
|
|
769
|
+
`currentHash`, `enabled: true`, and `trustStatus: "trusted"` for the installed
|
|
770
|
+
brindle hook. This read-only probe made no model calls or trust edits; hook
|
|
771
|
+
dispatch/allow/deny behavior is covered by the permission tests. Linux runtime
|
|
772
|
+
and native Windows behavior were not exercised by that probe.
|
|
773
|
+
`codex features list` also reported `hooks stable true` without a user
|
|
774
|
+
`features.hooks` setting, both on 0.162.1 and the bundled 0.158.0-alpha.2.1.
|
|
775
|
+
A session override of `features.hooks=false` reported false. No feature-enable
|
|
776
|
+
flag is needed on these versions, and brindle leaves explicit disablement alone.
|
|
777
|
+
|
|
684
778
|
**Antigravity.** agy's hook can deny but its "allow" is ignored (an agy bug),
|
|
685
779
|
and it has no "no opinion" answer. So the hook denies what the policy denies,
|
|
686
780
|
answers "allow" for a file inside the workspace (which agy reads and writes
|