# PRD 0030: Deduplicate egress token resolution across backends

- **Status:** Active
- **Author:** didericis-claude
- **Created:** 2026-06-02
- **Issue:** #118

## Summary

Eliminate the duplicated egress token resolution block — which resolved
manifest-declared tokens and the Codex host credential — by moving
provider-specific token reading into `AgentProvisionPlan.provisioned_env`
at prepare time, and having both backends merge that map into `os.environ`
before calling the now-generic `egress_resolve_token_values`.

## Problem

The same logic block appeared in two places:

- `bot_bottle/backend/docker/launch.py` (~line 183): inline inside
  `launch()`, building `token_values` before `compose_up`.
- `bot_bottle/backend/smolmachines/launch.py` (~line 422): the private
  `_resolve_token_env` helper, called before `_bundle.start_bundle`.

Both blocks:
1. Short-circuit to `{}` when there are no egress routes.
2. Call `egress_resolve_token_values(token_env_map, host_env)` to
   resolve ordinary manifest-declared token refs.
3. Check `agent_provider.forward_host_credentials` and, when true,
   call `codex_host_access_token` and slot the result into any
   `token_env` whose `token_ref` is `CODEX_HOST_CREDENTIAL_TOKEN_REF`.

The duplication means any change to step 3 must be applied twice.
PRD 0029, which introduced `forward_host_credentials`, already had to
wire both backends; the next change would too. This is a near-certain
future sync bug.

`egress_resolve_token_values` also carried a sentinel `continue` skip
for `CODEX_HOST_CREDENTIAL_TOKEN_REF`, which tied an otherwise generic
egress helper to a Codex-specific contract.

## Goals / Success Criteria

- The `forward_host_credentials` resolution logic exists in exactly one
  place in the codebase.
- Both `docker/launch.py` and `smolmachines/launch.py` call
  `egress_resolve_token_values` with no provider-specific arguments.
- `egress_resolve_token_values` is fully generic — it neither knows nor
  cares about provider identity or the `CODEX_HOST_CREDENTIAL_TOKEN_REF`
  sentinel.
- No behaviour change for either backend.

## Non-goals

- Changes to token resolution semantics. This is a pure refactor.
- Adding support for any new credential type or provider.
- Consolidating any other backend differences beyond this one block.

## Design

### `AgentProvisionPlan.provisioned_env`

Add `provisioned_env: dict[str, str]` (default empty) to
`AgentProvisionPlan`. This map holds host-side secrets that the
provisioning stage resolved and that egress needs injected into the
sidecar environ.

When `forward_host_credentials=True` for Codex, `agent_provision_plan`
calls `codex_host_access_token(host_env)` and stores the result under
`CODEX_HOST_CREDENTIAL_TOKEN_REF`. This is already the prepare-time
stage where `write_codex_dummy_auth_file` runs, so the access-token
read is colocated with all other Codex-specific provisioning.

### Backend call sites

Both backends merge `provisioned_env` over `os.environ` before calling
`egress_resolve_token_values`:

```python
effective_env = {**dict(os.environ), **plan.agent_provision.provisioned_env}
token_values = egress_resolve_token_values(plan.egress_plan.token_env_map, effective_env)
```

`provisioned_env` values take precedence over same-named host env vars,
so the Codex token slot resolves from the map written at prepare time
rather than from a raw `os.environ` lookup.

### `egress_resolve_token_values`

Remove the `CODEX_HOST_CREDENTIAL_TOKEN_REF` sentinel `continue` skip.
The function now resolves every slot in `token_env_map` from `host_env`
without special-casing any key name. The `CODEX_HOST_CREDENTIAL_TOKEN_REF`
key is present in `effective_env` (injected by `provisioned_env`) exactly
when it is needed.

## Implementation

- `bot_bottle/agent_provider.py`: add `provisioned_env` field; populate
  it for Codex when `forward_host_credentials=True`.
- `bot_bottle/egress.py`: remove sentinel skip; remove
  `egress_resolve_token_values_with_provider` (the intermediate function
  that was introduced and then superseded by this design); drop the
  `codex_auth` import.
- `bot_bottle/backend/docker/launch.py`: replace the provider-aware
  resolution block with the `effective_env` merge.
- `bot_bottle/backend/smolmachines/launch.py`: same replacement in
  `_resolve_token_env`.
- `tests/unit/test_agent_provider.py`: add tests verifying
  `provisioned_env` is populated (or empty) for Codex with and without
  `forward_host_credentials`.
- `tests/unit/test_egress.py`: remove `TestResolveTokenValuesWithProvider`;
  replace the sentinel-skip test with a test verifying the Codex token
  ref resolves normally when present in `host_env`.

## References

- Issue #118: Deduplicate egress token resolution across backends.
- Issue #117: Complexity hotspots in launch, egress, and auth paths
  (source of the finding).
- PRD 0029: Provider auth credentials through egress (introduced the
  duplicated block).
