feat(reviewer): cloud Ollama bearer auth via OLLAMA_API_KEY env #60

Merged
pdurlej merged 1 commit from claude/feat-cloud-ollama-auth into main 2026-05-27 23:42:41 +02:00
Collaborator

Why

pdurlej/platform#527 smoke test for the platform#524 wave revealed that patchwarden review-run, even after the MERGE_BASE workflow fix (platform#528), hits Connection refused against 127.0.0.1:11434 — there's no local Ollama on the runner and ollama_client.py had no way to authenticate against cloud Ollama. The reviewer lane is wired but cannot actually produce findings without local Ollama deployment.

This PR adds the missing pluming: optional bearer-token auth + env-var-driven endpoint override. Together with a runner-local PLATFORMCTL_CANARY_ENV setting OLLAMA_API_KEY (sourced from infisical:/home-platform/providers/OLLAMA_CLOUD_API_KEY) and OLLAMA_BASE_URL=https://ollama.com, the workflow can target cloud Ollama without changing the lane config or CLI invocation.

What changes

File Change
src/patchwarden/ollama_client.py OllamaRequest.api_key: str | None = None. _attempt builds the headers dict (Content-Type always; Authorization: Bearer when api_key truthy). _urllib_transport signature gains headers parameter and forwards it verbatim to urllib.request.Request. Transport type updated accordingly.
src/patchwarden/review_run.py _findings_from_ollama reads OLLAMA_BASE_URL + OLLAMA_API_KEY from os.environ and passes them to OllamaRequest. Both optional — unset leaves the dataclass defaults (127.0.0.1:11434, no auth) intact.
tests/test_ollama_client.py All transport mock stubs updated mechanically to accept the new headers parameter. New AuthHeaderTests (4 tests).
tests/test_review_run.py Transport mock stubs updated mechanically.

Backward compatibility

  • Local Ollama path unchanged: no OLLAMA_API_KEY set → no Authorization header → request looks identical to today's traffic.
  • OLLAMA_BASE_URL unset → falls back to OLLAMA_DEFAULT_BASE_URL = "http://127.0.0.1:11434".
  • OLLAMA_API_KEY="" (common env-var artifact) explicitly treated as no auth — never emits a malformed Bearer header.
  • Fallback model attempt reuses the same bearer (same endpoint = same auth scope; cloud fallback would 401 otherwise — covered by new test).

D20 sovereignty

Unchanged. This is transport plumbing only. The model still only suspects; Patchwarden's deterministic policy gate still decides merge eligibility. No new authority, no APPROVED path, no merge endpoint — tests/test_d20_architectural_boundary.py still passes.

D21 (M2 amendment) compatibility

This is wiring of an existing capability to a different endpoint, not a new core capability. It does not add a new CLI subcommand, does not change schema versions, does not bind new runtime deps (stdlib-only urllib already in use), does not expand the dogfood lane. It enables the existing Ollama call path to function in the actual deployment environment per platform#527 evidence.

Tests

PYTHONPATH=src python3 -m unittest discover tests
Ran 156 tests in 0.082s
OK

152 baseline + 4 new AuthHeaderTests:

  1. test_no_api_key_omits_authorization_header — default path stays unauthenticated
  2. test_api_key_sets_bearer_authorization_header — Bearer token format correct
  3. test_api_key_propagated_on_fallback_attempt — fallback reuses auth
  4. test_empty_string_api_key_treated_as_no_auth — empty env-var artifact safe

Smoke evidence after merge (planned)

  1. Operator updates runner-local PLATFORMCTL_CANARY_ENV file with:
    • OLLAMA_API_KEY=<infisical OLLAMA_CLOUD_API_KEY value>
    • OLLAMA_BASE_URL=https://ollama.com (or whichever cloud endpoint)
  2. pdurlej/platform#527 re-runs (push empty commit for synchronize).
  3. review-run reaches Ollama with auth → either gets real findings OR a meaningful HTTP response (not connection refused).
  4. post-findings --execute posts a comment to #527 — evidence-confirmed full loop.
  5. Follow-up PR in pdurlej/patchwarden updates docs/operations/dogfood-actual-vs-mental-model.md to mark Luka 1+2 as evidence-confirmed.

Refs: pdurlej/platform#527, pdurlej/platform#528, pdurlej/patchwarden#48 #49 #54

## Why `pdurlej/platform#527` smoke test for the `platform#524` wave revealed that `patchwarden review-run`, even after the `MERGE_BASE` workflow fix (`platform#528`), hits `Connection refused` against `127.0.0.1:11434` — there's no local Ollama on the runner and `ollama_client.py` had no way to authenticate against cloud Ollama. The reviewer lane is *wired* but cannot actually produce findings without local Ollama deployment. This PR adds the missing pluming: optional bearer-token auth + env-var-driven endpoint override. Together with a runner-local `PLATFORMCTL_CANARY_ENV` setting `OLLAMA_API_KEY` (sourced from `infisical:/home-platform/providers/OLLAMA_CLOUD_API_KEY`) and `OLLAMA_BASE_URL=https://ollama.com`, the workflow can target cloud Ollama without changing the lane config or CLI invocation. ## What changes | File | Change | |---|---| | `src/patchwarden/ollama_client.py` | `OllamaRequest.api_key: str \| None = None`. `_attempt` builds the headers dict (Content-Type always; Authorization: Bearer when api_key truthy). `_urllib_transport` signature gains `headers` parameter and forwards it verbatim to `urllib.request.Request`. `Transport` type updated accordingly. | | `src/patchwarden/review_run.py` | `_findings_from_ollama` reads `OLLAMA_BASE_URL` + `OLLAMA_API_KEY` from `os.environ` and passes them to `OllamaRequest`. Both optional — unset leaves the dataclass defaults (127.0.0.1:11434, no auth) intact. | | `tests/test_ollama_client.py` | All transport mock stubs updated mechanically to accept the new `headers` parameter. New `AuthHeaderTests` (4 tests). | | `tests/test_review_run.py` | Transport mock stubs updated mechanically. | ## Backward compatibility - Local Ollama path unchanged: no `OLLAMA_API_KEY` set → no `Authorization` header → request looks identical to today's traffic. - `OLLAMA_BASE_URL` unset → falls back to `OLLAMA_DEFAULT_BASE_URL = "http://127.0.0.1:11434"`. - `OLLAMA_API_KEY=""` (common env-var artifact) explicitly treated as no auth — never emits a malformed `Bearer ` header. - Fallback model attempt reuses the same bearer (same endpoint = same auth scope; cloud fallback would 401 otherwise — covered by new test). ## D20 sovereignty Unchanged. This is **transport plumbing** only. The model still only suspects; Patchwarden's deterministic policy gate still decides merge eligibility. No new authority, no APPROVED path, no merge endpoint — `tests/test_d20_architectural_boundary.py` still passes. ## D21 (M2 amendment) compatibility This is **wiring of an existing capability to a different endpoint**, not a new core capability. It does not add a new CLI subcommand, does not change schema versions, does not bind new runtime deps (stdlib-only urllib already in use), does not expand the dogfood lane. It enables the *existing* Ollama call path to function in the actual deployment environment per `platform#527` evidence. ## Tests ``` PYTHONPATH=src python3 -m unittest discover tests Ran 156 tests in 0.082s OK ``` 152 baseline + 4 new `AuthHeaderTests`: 1. `test_no_api_key_omits_authorization_header` — default path stays unauthenticated 2. `test_api_key_sets_bearer_authorization_header` — Bearer token format correct 3. `test_api_key_propagated_on_fallback_attempt` — fallback reuses auth 4. `test_empty_string_api_key_treated_as_no_auth` — empty env-var artifact safe ## Smoke evidence after merge (planned) 1. Operator updates runner-local `PLATFORMCTL_CANARY_ENV` file with: - `OLLAMA_API_KEY=<infisical OLLAMA_CLOUD_API_KEY value>` - `OLLAMA_BASE_URL=https://ollama.com` (or whichever cloud endpoint) 2. `pdurlej/platform#527` re-runs (push empty commit for `synchronize`). 3. `review-run` reaches Ollama with auth → either gets real findings OR a meaningful HTTP response (not connection refused). 4. `post-findings --execute` posts a comment to `#527` — evidence-confirmed full loop. 5. Follow-up PR in `pdurlej/patchwarden` updates `docs/operations/dogfood-actual-vs-mental-model.md` to mark Luka 1+2 as evidence-confirmed. Refs: `pdurlej/platform#527`, `pdurlej/platform#528`, `pdurlej/patchwarden#48 #49 #54`
Adds optional bearer-token authentication to the Ollama transport so
reviewer lanes can target cloud Ollama endpoints (e.g. ollama.com)
without changing lane config or CLI invocation.

Changes:
- OllamaRequest gains an `api_key: str | None = None` field. When
  present, _attempt adds `Authorization: Bearer <key>` to the headers
  passed to the transport. When None/empty, the header is omitted —
  local Ollama on 127.0.0.1:11434 keeps its existing unauthenticated
  path.
- Transport callable signature gains a `headers: dict[str, str]`
  parameter. _urllib_transport forwards the dict verbatim to urllib;
  the caller (_attempt) is now responsible for building Content-Type
  and conditional Authorization.
- review_run._findings_from_ollama reads OLLAMA_BASE_URL +
  OLLAMA_API_KEY from os.environ and propagates them onto the
  OllamaRequest. Both are optional; absence leaves the dataclass
  defaults (local URL, no auth) intact.

Backward compatibility:
- Existing test transport stubs updated mechanically to accept the
  new `headers` parameter. 152 baseline tests pass unchanged.
- Four new AuthHeaderTests cover: no-key omits Authorization, key
  sets Bearer header, fallback attempt reuses same auth (cloud
  fallback would 401 otherwise), empty-string key treated as no auth
  (common OLLAMA_API_KEY= env artifact).
- D20 sovereignty unchanged: the model still only suspects;
  Patchwarden's policy gate still decides. This PR is plumbing, not
  authority.

Tests: PYTHONPATH=src python3 -m unittest discover tests → 156/156 OK.

Wiring rationale (pdurlej/platform#527 evidence trail):
- run 2659/2664/2666: KeyError MERGE_BASE — fixed by pdurlej/platform#528
- run 2684 (rebased onto #528): review-run REACHES Ollama, then
  `[Errno 111] Connection refused` on 127.0.0.1:11434 — no local
  Ollama on runner. This PR + a runner-local PLATFORMCTL_CANARY_ENV
  setting OLLAMA_API_KEY (from infisical /home-platform/providers/
  OLLAMA_CLOUD_API_KEY) + OLLAMA_BASE_URL together close that gap
  without local Ollama deployment.

Refs: pdurlej/platform#527, pdurlej/platform#528,
      pdurlej/patchwarden#48 #49 #54

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
agent/claude-code
agent/codex
agent/gemini
agent/hermes
agent/iskra
agent/ollama
agent/patchwarden
area:business-model
area:competitive
area:discovery
area:forgejo
area:metrics
area:product-strategy
area:v0-core
cagan-grade-approved
client:platform
dependency/blocked
dependency/blocks-others
dependency/cross-repo
dependency/needs-confirmation
domain:agents
domain:ci
domain:docs
domain:forgejo
domain:infra
domain:memory
domain:runtime
domain:signal
domain:ux
flow/architecture
flow/blocked
flow/deployed
flow/done
flow/implementation
flow/intake
flow/maintained
flow/observed
flow/ready
flow/refining
flow/retired
flow/review
judge/codex-candidate
judge/hermes-candidate
judge/low-confidence
judge/needs-refinement
judge/operator-needed
judge/p0
judge/p1
judge/p2
judge/p3
judge/park
judge/patchwarden-candidate
judge/stale-priority
kind/adr
kind/bug
kind/chore
kind/feature
kind/infra
kind/ops
kind/refactor
kind/research
kind:artifact
kind:decision
kind:dogfood
kind:epic
kind:implementation
kind:research
merge/auto
merge/manual
merge/manual-dependency-conflict
merge/manual-failing-tests
merge/manual-merge-conflict
merge/manual-missing-review
merge/manual-operator-preference
merge/manual-red-zone
merge/manual-security-sensitive
merge/manual-unclear-scope
merge/manual-unknown
mode:operator-only
mode:patchwarden-iskra-approved
mode:safe-auto
observed/erroring
observed/needs-followup
observed/pending
observed/retire-candidate
observed/unused
observed/used
priority:p0
priority:p1
priority:p2
priority:p3
ready-for-agent
review:claude-reviewed
review:codex-reviewed
review:dziadek-reviewed
review:needs-human
safety:external-write
safety:no-prod-mutation
safety:prod-impact
safety:secret-touch
size/large
size/medium
size/small
size/tiny
size/unknown
source/adr
source/agent-generated
source/manual
source/operator-chat
source/voice-note
status:blocked
status:blocked-on-discovery
status:cagan-grade-review-pending
status:codex-ready
status:merged:pending-evidence
status:needs-evidence
status:needs-operator-decision
status:operator-needed
status:parked
tier:0-anchor
tier:0-platform-substrate
tier:1-core
tier:1-iskra-value-layer
tier:2-supporting
tier:2-tools-products-modules
type:bug
type:chore
type:docs
type:feat
type:policy
type:research
wave:1-foundation
wave:2-positioning
wave:3-validation
wave:4-economics
wave:5-operating
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pdurlej/patchwarden!60
No description provided.