Skip to content

Commit 801fe14

Browse files
OgeonX-AiAitomatesclaude
authored
fix: preserve adapter failure diagnostics (#7)
* chore: add codeowners and harden workflow permissions Enterprise governance hardening: - Add explicit /.github/ ownership to CODEOWNERS where missing. - Add top-level least-privilege permissions (default contents: read) to workflows lacking one, granting only the scopes each needs. - Add timeout-minutes to jobs missing one. YAML hardening only; no build logic, scripts, or step contents changed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(adapter): preserve transport failure causes --------- Co-authored-by: Kim Harjamäki <kim.harjamaki@prosimo.fi> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent eb26ff1 commit 801fe14

6 files changed

Lines changed: 39 additions & 4 deletions

File tree

.github/workflows/codeql.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ on:
44
branches: [ "main", "master" ]
55
pull_request:
66
branches: [ "main", "master" ]
7+
permissions:
8+
contents: read
9+
710
jobs:
811
analyze:
912
name: Analyze
1013
runs-on: ubuntu-latest
14+
timeout-minutes: 15
1115
permissions:
1216
actions: read
1317
contents: read

.github/workflows/pages.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ concurrency:
1414
jobs:
1515
build:
1616
runs-on: ubuntu-latest
17+
timeout-minutes: 10
1718
steps:
1819
- uses: actions/checkout@v4
1920
- uses: actions/setup-python@v5
@@ -29,6 +30,7 @@ jobs:
2930
name: github-pages
3031
url: ${{ steps.deployment.outputs.page_url }}
3132
runs-on: ubuntu-latest
33+
timeout-minutes: 10
3234
needs: build
3335
steps:
3436
- name: Deploy to GitHub Pages

.github/workflows/pr-lint.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@ on:
66
- edited
77
- synchronize
88

9+
permissions:
10+
contents: read
11+
pull-requests: read
12+
913
jobs:
1014
main:
1115
name: Validate PR title
1216
runs-on: ubuntu-latest
17+
timeout-minutes: 10
1318
steps:
1419
- uses: amannn/action-semantic-pull-request@v5
1520
env:

.github/workflows/stale.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@ on:
33
schedule:
44
- cron: '0 0 * * *'
55

6+
permissions:
7+
contents: read
8+
issues: write
9+
pull-requests: write
10+
611
jobs:
712
stale:
813
runs-on: ubuntu-latest
14+
timeout-minutes: 10
915
steps:
1016
- uses: actions/stale@v8
1117
with:

src/cas_evals/reference_product.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ def post(envelope: dict[str, Any]) -> dict[str, Any]:
4747
with urlopen(request, timeout=timeout_seconds) as response:
4848
payload = response.read(MAX_RESPONSE_BYTES + 1)
4949
except HTTPError as error:
50-
raise ReferenceProductError(f"reference product returned HTTP {error.code}") from None
51-
except (URLError, TimeoutError, OSError):
52-
raise ReferenceProductError("reference product is unavailable") from None
50+
raise ReferenceProductError(f"reference product returned HTTP {error.code}") from error
51+
except (URLError, TimeoutError, OSError) as error:
52+
raise ReferenceProductError("reference product is unavailable") from error
5353
if len(payload) > MAX_RESPONSE_BYTES:
5454
raise ReferenceProductError("reference product response exceeds the size limit")
5555
try:

tests/test_reference_product.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@
66
import unittest
77
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
88
from pathlib import Path
9+
from unittest.mock import patch
10+
from urllib.error import URLError
911

10-
from cas_evals.reference_product import ReferenceProductError, evaluate_reference_suite
12+
from cas_evals.reference_product import (
13+
ReferenceProductError,
14+
_http_transport,
15+
evaluate_reference_suite,
16+
)
1117

1218
ROOT = Path(__file__).parents[1]
1319
GOLDEN = ROOT / "benchmarks/reference-product/v0.1/golden.json"
@@ -105,6 +111,18 @@ def test_invalid_endpoint_and_timeout_fail_closed(self):
105111
with self.assertRaises(ReferenceProductError):
106112
evaluate_reference_suite(GOLDEN, timeout_seconds=0)
107113

114+
def test_network_failure_preserves_root_cause(self):
115+
failure = URLError("network unavailable")
116+
transport = _http_transport("http://127.0.0.1:8080/api/v1/workflows", 1.0)
117+
118+
with patch("cas_evals.reference_product.urlopen", side_effect=failure):
119+
with self.assertRaisesRegex(
120+
ReferenceProductError, "reference product is unavailable"
121+
) as caught:
122+
transport({"kind": "PromptEnvelope"})
123+
124+
self.assertIs(caught.exception.__cause__, failure)
125+
108126
def test_http_endpoint_is_executable(self):
109127
server = ThreadingHTTPServer(("127.0.0.1", 0), ReferenceHandler)
110128
thread = threading.Thread(target=server.serve_forever, daemon=True)

0 commit comments

Comments
 (0)