diff --git a/CHANGELOG.d/20260930-strix-parallel-request-executable-bound.md b/CHANGELOG.d/20260930-strix-parallel-request-executable-bound.md new file mode 100644 index 0000000000..6f51bac707 --- /dev/null +++ b/CHANGELOG.d/20260930-strix-parallel-request-executable-bound.md @@ -0,0 +1,4 @@ +## Fixed + +- Execute the Strix sidecar concurrency contract in tests so a matching source + string cannot stand in for the configured `SecurityConfig` request bound. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index d4bedf024c..fe4a0000d2 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -7,6 +7,12 @@ 이 문서는 제품·기술·운영 Gap을 현재 문서와 현재 GitHub 상태에 묶어 두는 기준선이다. 새 작업은 먼저 이 문서의 Gap ID를 PR 설명과 테스트 증거에 연결하고, PR의 정확한 exact HEAD·Checks·리뷰를 다시 수집한 뒤 구현한다. 표의 상태는 작성 시점의 관측값이므로, 병합 판단에는 재사용하지 않는다. 이 인벤토리는 스냅샷이며 merge authorization이 아니다. +### 2026-09-30 Strix parallel-request capacity delta + +| Gap ID | 상태 | exact evidence | causal owner / next gate | +|---|---|---|---| +| CONTROL-STRIX-PARALLEL-REQUEST-CAPACITY-03 | **Proposed — executable config repair; hosted exact-head acceptance pending** | `.github#2490`은 Strix 병렬 Agent 요청이 generic 8-slot bound를 소진한 증거에 따라 16-slot sidecar bound를 제안했다. 기존 회귀는 source 문자열만 확인해 실제 `SecurityConfig` 값과 무관하게 통과할 수 있었다. RED `85bdcc5bd7f31e7b13fb500af1dba2750d8b6825`은 실행 가능한 config factory를 요구하고, GREEN `acee83861ee59f986157c14a81ad8d70eb4f2bc3`은 production call과 test를 같은 factory에 묶었다. protected `main@37b10243cec3d160ecc9c1be75c71428b160a703` 통합은 ordinary merge `a57e32ae0d87d5b28179c402b66019bbed4e856d`다. | Canonical owner는 중앙 review sidecar launcher다. fresh exact-head hosted security/coverage/review Checks와 independent approval이 terminal GREEN이 되기 전에는 Accepted·merge authority가 아니다. | + ### 2026-09-30 central coverage owner stack delta | Gap ID | 상태 | exact-head evidence | causal owner / next gate | diff --git a/scripts/ci/contextual_orchestrator_review_launcher.py b/scripts/ci/contextual_orchestrator_review_launcher.py index 8d5fe6c100..713714df8e 100644 --- a/scripts/ci/contextual_orchestrator_review_launcher.py +++ b/scripts/ci/contextual_orchestrator_review_launcher.py @@ -1191,6 +1191,17 @@ def _load_temporary_agents( catalog_path.unlink(missing_ok=True) +def _review_security_config(factory: Callable[..., Any], auth_token: str) -> Any: + """Build the loopback review server's bounded request security contract.""" + return factory( + auth_token=auth_token, + max_body_bytes=REVIEW_MAX_BODY_BYTES, + # Strix exhausted the generic eight-slot limit on PR #1227 while + # its parallel agents were still making successful provider calls. + max_concurrent_runs=16, + ) + + def main(argv: list[str] | None = None) -> int: """Bootstrap the KV, discover and preflight free models, then serve. @@ -1392,10 +1403,7 @@ def main(argv: list[str] | None = None) -> int: orchestrator, host=args.host, port=args.port, - security=SecurityConfig( - auth_token=auth_token, - max_body_bytes=REVIEW_MAX_BODY_BYTES, - ), + security=_review_security_config(SecurityConfig, auth_token), ) return 0 diff --git a/tests/test_contextual_orchestrator_review_launcher.py b/tests/test_contextual_orchestrator_review_launcher.py index 50d484da9c..91f3b6fdc3 100644 --- a/tests/test_contextual_orchestrator_review_launcher.py +++ b/tests/test_contextual_orchestrator_review_launcher.py @@ -149,9 +149,16 @@ def load_agents(catalog_path: str) -> list[SimpleNamespace]: class SecurityConfig: """Retain the authentication boundary passed to the server.""" - def __init__(self, *, auth_token: str, max_body_bytes: int) -> None: + def __init__( + self, + *, + auth_token: str, + max_body_bytes: int, + max_concurrent_runs: int, + ) -> None: self.auth_token = auth_token self.max_body_bytes = max_body_bytes + self.max_concurrent_runs = max_concurrent_runs def serve( orchestrator: object, @@ -234,6 +241,7 @@ def test_main_serves_a_discovered_free_route( assert served_request.port == 18080 assert served_request.security.auth_token == "gateway-token" assert served_request.security.max_body_bytes == launcher.REVIEW_MAX_BODY_BYTES + assert served_request.security.max_concurrent_runs == 16 assert [agent.id for agent in served_request.orchestrator.agents] == [ "bytez_free" ] diff --git a/tests/test_contextual_orchestrator_review_sidecar_contract.py b/tests/test_contextual_orchestrator_review_sidecar_contract.py index 16b85c5c78..ac6a61a163 100644 --- a/tests/test_contextual_orchestrator_review_sidecar_contract.py +++ b/tests/test_contextual_orchestrator_review_sidecar_contract.py @@ -388,6 +388,17 @@ def test_launcher_sets_a_bounded_review_request_body_limit() -> None: assert "max_body_bytes=REVIEW_MAX_BODY_BYTES" in text +def test_launcher_builds_parallel_strix_security_config() -> None: + """Exercise the configured bound instead of accepting a matching source string.""" + launcher = runpy.run_path(str(LAUNCHER)) + security_config = launcher["_review_security_config"]( + SimpleNamespace, "synthetic-test-bearer" + ) + assert security_config.auth_token == "synthetic-test-bearer" + assert security_config.max_body_bytes == 512 * 1024 * 1024 + assert security_config.max_concurrent_runs == 16 + + def test_strix_gateway_uses_provider_neutral_reasoning_effort() -> None: """Gateway free-pool scans must not force unsupported provider controls.""" text = _read(STRIX_WORKFLOW)