Operators can now declare:
agent_provider:
template: claude
auth_token: BOT_BOTTLE_CLAUDE_OAUTH_TOKEN
and the provisioner injects a provider-owned api.anthropic.com egress
route (Bearer, tls_passthrough) rather than requiring a manually
declared route with the former claude_code_oauth role.
Changes:
- Add auth_token field to AgentProvider; validate claude-only.
- Remove claude_code_oauth from EGRESS_ROLES / PROVIDER_EGRESS_ROLES.
Manifests that declare the role now fail at parse time with "unknown
role" — the provisioner owns the route.
- agent_provision_plan: replace manifest_egress_routes/has_provider_auth
with auth_token; Claude branch injects the api.anthropic.com route,
placeholder env, and nonessential-traffic flags when auth_token is set.
- Add hidden_env_names: frozenset[str] to AgentProvisionPlan; Claude
branch populates it with CLAUDE_CODE_OAUTH_TOKEN.
- Remove auth_role from AgentProviderRuntime and placeholder_env_for().
- print_util.visible_agent_env_names: accept hidden_env_names from the
plan instead of dispatching on agent_provider_template.
- Both backends: drop manifest_egress_routes call, pass auth_token.
- PRD 0029 rescoped to cover both Codex and Claude provider auth.
Assisted-by: Claude Code
Product requirement docs
One PRD per feature: what to build, why, and how it's scoped. The PRD
is the durable spec — it should stand on its own without a Gitea issue
thread (see ../README.md for when a PRD is the right
document vs. a research note or a decision record).
Naming and numbering
NNNN-kebab-title.md, zero-padded and sequential (0024-…, 0025-…).
Numbers are never reused; gaps are fine (there is no 0005). The number
is assigned at creation and stays fixed for the life of the doc.
Status
The Status: line near the top tracks the PRD's lifecycle:
- Draft — proposed, not yet shipped.
- Active — the design has shipped to
mainand is in effect. - Superseded by PRD NNNN — replaced by a later PRD; kept for history.
- Retargeted by PRD NNNN — folded into a later PRD's scope.
Format
# PRD NNNN: <short title>
- **Status:** Draft
- **Author:** <who>
- **Created:** YYYY-MM-DD
- **Issue:** #<n> # optional — convenience pointer only
## Summary
One paragraph: what this builds and the pain it solves.
## Problem
The current state and why it's inadequate.
## Goals / Success Criteria
Bullets a reviewer can check the finished work against.
## Non-goals
What this explicitly does not do — and won't, to head off scope creep.
## Scope
In scope / out of scope, when the boundary needs spelling out.
## Design
How it works: schema, data flow, diagrams, algorithms as needed.
## Implementation chunks
Ordered, mergeable steps (optional; for multi-PR features).
## Open questions
Unresolved decisions — resolve or fold into Design before shipping.
Sections are a guide, not a straitjacket: drop the ones a given PRD doesn't need (a small change rarely needs Scope or Implementation chunks) and add others where they help (e.g. Testing strategy, Alternatives considered, References). Keep the rationale self-contained — inline the reasoning rather than linking out to an issue thread, so the PRD survives a move off Gitea.