brindle 0.0.4__tar.gz → 0.0.6__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 (88) hide show
  1. {brindle-0.0.4 → brindle-0.0.6}/PKG-INFO +49 -6
  2. {brindle-0.0.4 → brindle-0.0.6}/README.md +48 -5
  3. {brindle-0.0.4 → brindle-0.0.6}/pyproject.toml +1 -1
  4. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/ci_adapters.py +2 -1
  5. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/ci_client.py +458 -71
  6. brindle-0.0.6/src/brindle/ci_federation.py +402 -0
  7. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/cli.py +22 -4
  8. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/tmux.py +57 -0
  9. {brindle-0.0.4 → brindle-0.0.6}/.gitignore +0 -0
  10. {brindle-0.0.4 → brindle-0.0.6}/LICENSE +0 -0
  11. {brindle-0.0.4 → brindle-0.0.6}/SCHEDULE-A +0 -0
  12. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/__init__.py +0 -0
  13. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/__main__.py +0 -0
  14. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/account.py +0 -0
  15. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/agents.py +0 -0
  16. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/airgap.py +0 -0
  17. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/antigravity.py +0 -0
  18. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/autopilot.py +0 -0
  19. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/__init__.py +0 -0
  20. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/developer-codex.md +0 -0
  21. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/developer-heavy.md +0 -0
  22. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/developer-local.md +0 -0
  23. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/developer.md +0 -0
  24. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/reviewer-codex.md +0 -0
  25. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/reviewer-local.md +0 -0
  26. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/reviewer.md +0 -0
  27. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/subagent.md +0 -0
  28. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/supervisor.md +0 -0
  29. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/codemap.py +0 -0
  30. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/codex_hook.py +0 -0
  31. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/config.py +0 -0
  32. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/cull.py +0 -0
  33. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/db.py +0 -0
  34. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/demo.py +0 -0
  35. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/detect.py +0 -0
  36. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/doctor.py +0 -0
  37. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/events.py +0 -0
  38. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/gates.py +0 -0
  39. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/git.py +0 -0
  40. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/history.py +0 -0
  41. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/inbox.py +0 -0
  42. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/learning.py +0 -0
  43. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/legacy.py +0 -0
  44. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/mcp_server.py +0 -0
  45. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/__init__.py +0 -0
  46. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/client.py +0 -0
  47. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/loop.py +0 -0
  48. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/permissions.py +0 -0
  49. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/runner.py +0 -0
  50. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/serve.py +0 -0
  51. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/tools.py +0 -0
  52. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/permissions.py +0 -0
  53. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pipeline.py +0 -0
  54. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/plugins.py +0 -0
  55. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/policy.py +0 -0
  56. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pool.py +0 -0
  57. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/__init__.py +0 -0
  58. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/_files.py +0 -0
  59. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/account.py +0 -0
  60. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/audit_chain.py +0 -0
  61. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/auth.py +0 -0
  62. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/credentials.py +0 -0
  63. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/features.py +0 -0
  64. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/keys.py +0 -0
  65. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/learning.py +0 -0
  66. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/license.py +0 -0
  67. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/loopback.py +0 -0
  68. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/orgkey.py +0 -0
  69. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/settings_sync.py +0 -0
  70. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/team_events.py +0 -0
  71. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/team_policy.py +0 -0
  72. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/procs.py +0 -0
  73. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/profiles.py +0 -0
  74. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/providers.py +0 -0
  75. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/quota.py +0 -0
  76. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/repo_cmds.py +0 -0
  77. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/repos.py +0 -0
  78. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/savings.py +0 -0
  79. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/scratch.py +0 -0
  80. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/services.py +0 -0
  81. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/sessions.py +0 -0
  82. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/sidebar_follow.py +0 -0
  83. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/status_cache.py +0 -0
  84. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/tasks.py +0 -0
  85. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/usage.py +0 -0
  86. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/view.py +0 -0
  87. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/watch.py +0 -0
  88. {brindle-0.0.4 → brindle-0.0.6}/src/brindle/workspaces.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brindle
3
- Version: 0.0.4
3
+ Version: 0.0.6
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.0.4`). A session started before an upgrade keeps
92
+ session shows it too (`brindle 0.0.6`). 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
@@ -148,7 +148,15 @@ a dim ◇ instead, because the supervisor reviews it.
148
148
 
149
149
  **Copying chat text.** Drag with the mouse in the chat: the selection stays inside
150
150
  that pane and is copied to the system clipboard (`pbcopy`, `wl-copy` or `xclip`;
151
- `brindle doctor` shows which). `h` in the sidebar hides it without quitting brindle
151
+ `brindle doctor` shows which); a double or triple click copies the word or line.
152
+ tmux keeps the mouse in the chat even though Claude Code asks to track it, so a
153
+ click only focuses the pane (and can't park Claude Code's focus in a dialog where
154
+ Esc stops working); the wheel still scrolls the chat. If Claude Code's Settings
155
+ dialog (`/usage`, `/config`) ever ignores Esc, its filter box has the focus: press
156
+ Esc up to three times (clear, leave the box, close), or `↓` then Esc. Don't reach
157
+ for Ctrl-C twice, which quits Claude Code and pauses the session.
158
+
159
+ **Hiding the sidebar.** `h` in the sidebar hides it without quitting brindle
152
160
  (the chat zooms; `Ctrl-b S` brings it back), and `Ctrl-b z` zooms the chat by hand.
153
161
  If the sidebar got left behind in another tmux session, `Ctrl-b S` in a window
154
162
  without one pulls it here, as does `brindle sidebar` (it restarts a sidebar that was closed).
@@ -820,7 +828,12 @@ workflows call these commands:
820
828
  checkout of the repository. For Claude it asks whether to use an API key
821
829
  (the `ANTHROPIC_API_KEY` secret) or Anthropic
822
830
  [workload identity federation](https://platform.claude.com/docs/en/manage-claude/wif-reference)
823
- (`--credential key|federation` answers without asking).
831
+ (`--credential key|federation` answers without asking). It also creates the
832
+ `brindle` issue label (label an issue with it to hand it to brindle CI), and
833
+ commits the workflows on a `brindle/ci-setup` branch, then puts you back on
834
+ the branch you started on and deletes the local setup branch, so `git pull`
835
+ after merging the setup pull request is clean (commit or stash your changes
836
+ first: it refuses to start with uncommitted work).
824
837
  - `brindle ci doctor`: which provider CLIs and credential names a runner has, and
825
838
  which providers CI may use on this repository.
826
839
  - `brindle ci start`: start a run for an issue, a goal text or a dispatched run,
@@ -832,6 +845,16 @@ workflows call these commands:
832
845
  Credential names are reported, never values. On a repository owned by a GitHub
833
846
  organization, a provider signed in only with a personal subscription is not used.
834
847
 
848
+ Fix builds only fix the default branch's *required* status checks, and a new
849
+ repository has none. When the default branch requires none, `brindle ci init`
850
+ warns and, for each job in your workflows, asks whether to make it required
851
+ (`--required-check NAME` picks one without asking, `--no-required-check` only
852
+ warns; run without a terminal, init only makes a check required when
853
+ `--required-check` names it). It adds the check to the branch's existing protection, or protects the
854
+ branch with just that check. GitHub only allows branch protection on a private
855
+ repository with a paid plan; when it refuses, init says how to require the
856
+ check yourself (Settings > Branches, "Require status checks to pass").
857
+
835
858
  An Anthropic API key is either a workspace key (scoped to one workspace) or an
836
859
  organization-level key (not scoped to a workspace). An organization-level key
837
860
  needs the workspace in every request, so after the key `brindle ci init` asks for
@@ -848,20 +871,40 @@ organization repositories), and gives the job `ANTHROPIC_AUTH_TOKEN`. `brindle
848
871
  ci init` stores the rule, organization, service account and optional workspace
849
872
  IDs as the Actions variables `ANTHROPIC_FEDERATION_RULE_ID`,
850
873
  `ANTHROPIC_ORGANIZATION_ID`, `ANTHROPIC_SERVICE_ACCOUNT_ID` and
851
- `ANTHROPIC_WORKSPACE_ID`. Create the federation rule in the Claude Console with
874
+ `ANTHROPIC_WORKSPACE_ID`, from `--rule-id`, `--organization-id`,
875
+ `--service-account-id` and `--workspace-id` or else asked (defaulting to those
876
+ environment variables). Without a terminal on stdin, init asks nothing and
877
+ takes the options and the environment, so it can run unattended; a missing or
878
+ malformed ID (rule `fdrl_...`, organization a UUID, service account
879
+ `svac_...`, workspace `wrkspc_...`) stops it before it creates the CI token.
880
+ The ID options imply `--credential federation` and can't be combined with
881
+ `--credential key`. Create the federation rule in the Claude Console with
852
882
  subject prefix `repo:<owner>/<name>:*`, the condition
853
883
 
854
884
  ```text
855
885
  claims.repository == "<owner>/<name>" && claims.workflow_ref.startsWith("<owner>/<name>/.github/workflows/brindle-ci-")
856
886
  ```
857
887
 
858
- audience `https://api.anthropic.com`, and a token lifetime of at least 7200
888
+ audience `https://api.anthropic.com`, and a token lifetime of at least 600
859
889
  seconds. The condition lets only brindle's workflows mint tokens. On pull
860
890
  requests the pull request's own copy of the validate workflow runs, so give
861
891
  write access only to people you trust (forks never get a token). Leave the `ANTHROPIC_API_KEY` secret
862
892
  unset: a key takes precedence (brindle drops an empty one before Claude Code
863
893
  starts).
864
894
 
895
+ A federated token lives at most about ten minutes, however long the rule
896
+ allows: Anthropic caps it at twice what remains of GitHub's OIDC token. So
897
+ the run job doesn't rely on the workflow's one exchange: `brindle ci run`
898
+ fetches a fresh OIDC token and exchanges it again at 70% of each token's
899
+ life, and lends the current token to the agents through a proxy on the
900
+ runner's loopback interface. The agents get `ANTHROPIC_BASE_URL` pointing at
901
+ it and a random per-run secret as `ANTHROPIC_AUTH_TOKEN`; the Anthropic token
902
+ itself stays in the `brindle ci run` process, and the GitHub token endpoint
903
+ (`ACTIONS_ID_TOKEN_REQUEST_URL` and its token) is scrubbed before any agent or
904
+ check starts. If the first exchange fails, the run goes on with the
905
+ workflow's token as before; `BRINDLE_CI_FEDERATION_REFRESH=0` in the job's
906
+ environment turns the refresh off.
907
+
865
908
  **Closing and cleaning up.** Press `x` on an agent in the sidebar (twice for one
866
909
  that's still running) or run `brindle close <id>` to stop it and hide it. Stopping means
867
910
  every process of the agent, not just its window: Claude Code can host a session in its
@@ -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.0.4`). A session started before an upgrade keeps
62
+ session shows it too (`brindle 0.0.6`). 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
@@ -118,7 +118,15 @@ a dim ◇ instead, because the supervisor reviews it.
118
118
 
119
119
  **Copying chat text.** Drag with the mouse in the chat: the selection stays inside
120
120
  that pane and is copied to the system clipboard (`pbcopy`, `wl-copy` or `xclip`;
121
- `brindle doctor` shows which). `h` in the sidebar hides it without quitting brindle
121
+ `brindle doctor` shows which); a double or triple click copies the word or line.
122
+ tmux keeps the mouse in the chat even though Claude Code asks to track it, so a
123
+ click only focuses the pane (and can't park Claude Code's focus in a dialog where
124
+ Esc stops working); the wheel still scrolls the chat. If Claude Code's Settings
125
+ dialog (`/usage`, `/config`) ever ignores Esc, its filter box has the focus: press
126
+ Esc up to three times (clear, leave the box, close), or `↓` then Esc. Don't reach
127
+ for Ctrl-C twice, which quits Claude Code and pauses the session.
128
+
129
+ **Hiding the sidebar.** `h` in the sidebar hides it without quitting brindle
122
130
  (the chat zooms; `Ctrl-b S` brings it back), and `Ctrl-b z` zooms the chat by hand.
123
131
  If the sidebar got left behind in another tmux session, `Ctrl-b S` in a window
124
132
  without one pulls it here, as does `brindle sidebar` (it restarts a sidebar that was closed).
@@ -790,7 +798,12 @@ workflows call these commands:
790
798
  checkout of the repository. For Claude it asks whether to use an API key
791
799
  (the `ANTHROPIC_API_KEY` secret) or Anthropic
792
800
  [workload identity federation](https://platform.claude.com/docs/en/manage-claude/wif-reference)
793
- (`--credential key|federation` answers without asking).
801
+ (`--credential key|federation` answers without asking). It also creates the
802
+ `brindle` issue label (label an issue with it to hand it to brindle CI), and
803
+ commits the workflows on a `brindle/ci-setup` branch, then puts you back on
804
+ the branch you started on and deletes the local setup branch, so `git pull`
805
+ after merging the setup pull request is clean (commit or stash your changes
806
+ first: it refuses to start with uncommitted work).
794
807
  - `brindle ci doctor`: which provider CLIs and credential names a runner has, and
795
808
  which providers CI may use on this repository.
796
809
  - `brindle ci start`: start a run for an issue, a goal text or a dispatched run,
@@ -802,6 +815,16 @@ workflows call these commands:
802
815
  Credential names are reported, never values. On a repository owned by a GitHub
803
816
  organization, a provider signed in only with a personal subscription is not used.
804
817
 
818
+ Fix builds only fix the default branch's *required* status checks, and a new
819
+ repository has none. When the default branch requires none, `brindle ci init`
820
+ warns and, for each job in your workflows, asks whether to make it required
821
+ (`--required-check NAME` picks one without asking, `--no-required-check` only
822
+ warns; run without a terminal, init only makes a check required when
823
+ `--required-check` names it). It adds the check to the branch's existing protection, or protects the
824
+ branch with just that check. GitHub only allows branch protection on a private
825
+ repository with a paid plan; when it refuses, init says how to require the
826
+ check yourself (Settings > Branches, "Require status checks to pass").
827
+
805
828
  An Anthropic API key is either a workspace key (scoped to one workspace) or an
806
829
  organization-level key (not scoped to a workspace). An organization-level key
807
830
  needs the workspace in every request, so after the key `brindle ci init` asks for
@@ -818,20 +841,40 @@ organization repositories), and gives the job `ANTHROPIC_AUTH_TOKEN`. `brindle
818
841
  ci init` stores the rule, organization, service account and optional workspace
819
842
  IDs as the Actions variables `ANTHROPIC_FEDERATION_RULE_ID`,
820
843
  `ANTHROPIC_ORGANIZATION_ID`, `ANTHROPIC_SERVICE_ACCOUNT_ID` and
821
- `ANTHROPIC_WORKSPACE_ID`. Create the federation rule in the Claude Console with
844
+ `ANTHROPIC_WORKSPACE_ID`, from `--rule-id`, `--organization-id`,
845
+ `--service-account-id` and `--workspace-id` or else asked (defaulting to those
846
+ environment variables). Without a terminal on stdin, init asks nothing and
847
+ takes the options and the environment, so it can run unattended; a missing or
848
+ malformed ID (rule `fdrl_...`, organization a UUID, service account
849
+ `svac_...`, workspace `wrkspc_...`) stops it before it creates the CI token.
850
+ The ID options imply `--credential federation` and can't be combined with
851
+ `--credential key`. Create the federation rule in the Claude Console with
822
852
  subject prefix `repo:<owner>/<name>:*`, the condition
823
853
 
824
854
  ```text
825
855
  claims.repository == "<owner>/<name>" && claims.workflow_ref.startsWith("<owner>/<name>/.github/workflows/brindle-ci-")
826
856
  ```
827
857
 
828
- audience `https://api.anthropic.com`, and a token lifetime of at least 7200
858
+ audience `https://api.anthropic.com`, and a token lifetime of at least 600
829
859
  seconds. The condition lets only brindle's workflows mint tokens. On pull
830
860
  requests the pull request's own copy of the validate workflow runs, so give
831
861
  write access only to people you trust (forks never get a token). Leave the `ANTHROPIC_API_KEY` secret
832
862
  unset: a key takes precedence (brindle drops an empty one before Claude Code
833
863
  starts).
834
864
 
865
+ A federated token lives at most about ten minutes, however long the rule
866
+ allows: Anthropic caps it at twice what remains of GitHub's OIDC token. So
867
+ the run job doesn't rely on the workflow's one exchange: `brindle ci run`
868
+ fetches a fresh OIDC token and exchanges it again at 70% of each token's
869
+ life, and lends the current token to the agents through a proxy on the
870
+ runner's loopback interface. The agents get `ANTHROPIC_BASE_URL` pointing at
871
+ it and a random per-run secret as `ANTHROPIC_AUTH_TOKEN`; the Anthropic token
872
+ itself stays in the `brindle ci run` process, and the GitHub token endpoint
873
+ (`ACTIONS_ID_TOKEN_REQUEST_URL` and its token) is scrubbed before any agent or
874
+ check starts. If the first exchange fails, the run goes on with the
875
+ workflow's token as before; `BRINDLE_CI_FEDERATION_REFRESH=0` in the job's
876
+ environment turns the refresh off.
877
+
835
878
  **Closing and cleaning up.** Press `x` on an agent in the sidebar (twice for one
836
879
  that's still running) or run `brindle close <id>` to stop it and hide it. Stopping means
837
880
  every process of the agent, not just its window: Claude Code can host a session in its
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "brindle"
3
- version = "0.0.4"
3
+ version = "0.0.6"
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"
@@ -11,7 +11,8 @@ An adapter answers four questions and does three things:
11
11
  endpoint without a key, or a personal subscription (``CLAUDE_CODE_OAUTH_TOKEN``;
12
12
  a ChatGPT login for Codex). Anthropic workload identity federation reaches
13
13
  here as an API key: the workflow exchanges GitHub's OIDC token once and
14
- gives the job ``ANTHROPIC_AUTH_TOKEN``.
14
+ gives the job ``ANTHROPIC_AUTH_TOKEN``; during the run that variable holds
15
+ the secret of brindle's own credential proxy (:mod:`brindle.ci_federation`).
15
16
  * ``available(env)``: installed and holding some credential.
16
17
  * ``launch``: start a brindle autopilot supervisor with the plan's instructions.
17
18
  * ``review``: ask the model one question (the plan's instructions) and return