Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/opencode-review-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,8 @@ jobs:
python_root=''; \
candidate_count=0; \
for candidate in \
"$destination/python/$import_name" \
"$destination/python/$import_name.py" \
"$destination/src/$import_name" \
"$destination/src/$import_name.py" \
"$destination/$import_name" \
Expand Down Expand Up @@ -870,6 +872,7 @@ jobs:
exit 1; \
fi; \
case "$import_root" in \
"$destination/python/"*) python_root="$destination/python" ;; \
"$destination/src/"*) python_root="$destination/src" ;; \
*) python_root="$destination" ;; \
esac; \
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
### OpenCode coverage admits immutable `python/` VCS source roots

- Central OpenCode coverage run [34701472466](https://github.com/ContextualWisdomLab/.github/actions/runs/34701472466) failed before executing `contextual-orchestrator#1149`: the trusted image builder resolved VCS packages only from repository root or `src/`, while the exact immutable `fast-mlsirm@09f762ded35786dd1078222a4577ff09d649816f` exposes `fast_mlsirm` from `python/fast_mlsirm`. The builder now admits the explicit `python/` source root, retains the one-and-only-one import-root invariant, symlink/namespace/compiled-artifact/installed-metadata rejection, exact commit verification, and the later credential-free networkless sandbox. Contract tests pin both package and single-module `python/` layouts. Refs `contextual-orchestrator#1149`. Exact-head Runtime Quality [job 103581110552](https://github.com/ContextualWisdomLab/.github/actions/runs/34704176931/job/103581110552) then caught the required independent workflow-blob trust pin still naming the predecessor blob; `683cb053` advances only that pin to exact blob `f315683208d57ba89a2942502c525abe7355e2fd`.

### Contextual-orchestrator pin advance removes the implicit 90 s model request timeout

- Advanced the central sidecar's pinned immutable CO revision from `414f2297` to protected `main@767e67fbc6b881a452761f32abb69b9971b9b03b`, carrying contextual-orchestrator#1053 into Strix, OpenCode, and Noema. Root cause: `ModelClient.__init__` defaulted `timeout=90`, and the review gateway constructed its client without a timeout, so long structured-output completions on NVIDIA NIM (`google/gemma-4-31b-it`) hit `TimeoutError` at exactly 90 s on every attempt; the orchestrator then cycled circuit open/reset on the same route for ~20 min and answered `502 provider_connection_error` (fast-mlsirm#1860 run 34748511702, sidecar artifact 10315556637: 15 of 27 failed attempts at 90.0 s; fast-mlsirm#1825 run 34752130895 same signature). #1053 removes the implicit deadline (null by default, administrator `model_timeout_seconds` per model) and was merged under the infrastructure exception because the pre-fix sidecar was failing its own Noema/OpenCode gates. Hosted acceptance is the first Noema/OpenCode/Strix run on this pin against a consumer PR; not claimed here. Refs ContextualWisdomLab/contextual-orchestrator#1053, ContextualWisdomLab/fast-mlsirm#1860.
Expand Down
28 changes: 28 additions & 0 deletions docs/doctoring/opencode-vcs-python-source-root.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# OpenCode immutable VCS `python/` source-root RCA

Status: **Proposed** — source repair exists on an open pull request; it is not protected-branch authority until merged.

## Incident and user-visible failure

On 2026-09-12 UTC, central OpenCode dispatch [run 34701472466](https://github.com/ContextualWisdomLab/.github/actions/runs/34701472466) validated `ContextualWisdomLab/contextual-orchestrator#1149` at exact head `684cf28fa59e800c0db4886a08f25dd2edd156fc`. Its `coverage-source-tree` job succeeded, but `coverage-evidence` job `103574547257` failed while building the trusted tool image, before any pull-request test or coverage command ran. OpenCode therefore published only a non-approving COMMENTED review, and the required receipt remained fail-closed.

The failing dependency was the exact VCS pin `fast-mlsirm@09f762ded35786dd1078222a4577ff09d649816f` from the consumer's validated `pyproject.toml`. That commit contains `python/fast_mlsirm/__init__.py`; it does not expose the import package at repository root or under `src/`.

## Root cause and boundary

`opencode-review-dispatch.yml` enumerated only four trusted candidates: `src/<import>`, `src/<import>.py`, `<import>`, and `<import>.py`. The materializer had already authenticated the target repository, bound the dependency to an immutable commit, fetched that commit without tags, and verified `FETCH_HEAD` and `HEAD`; the failure was solely an incomplete source-layout contract in the central owner.

The selected repair adds only `python/<import>` and `python/<import>.py`, then maps a match to the repository's `python/` directory. It preserves the invariant that exactly one candidate may exist and continues to reject symlinked/namespace imports, any symlink layout, compiled extensions, installed distribution metadata, and ambiguous roots. It does not infer arbitrary paths from untrusted packaging metadata and does not execute dependency lifecycle code.

Rejected alternatives were: changing the consumer's valid immutable dependency pin; copying `fast-mlsirm` into the consumer; adding the whole repository to `PYTHONPATH`; recursively searching for a matching directory; or weakening/bypassing the OpenCode coverage gate. Each would move ownership, admit ambiguity, or hide the central defect.

## RED → repair → verification gate

- RED commit `b1fe97c477b56e148afbeeaed9a6b74338994b6b` requires both package and single-module `python/` candidates in the published workflow contract.
- Repair commit `af04581cea4ffc038c881c6ad101ea3e5842a664` adds those candidates and the corresponding `python_root` mapping.
- Hosted Runtime Quality [job `103581110552`](https://github.com/ContextualWisdomLab/.github/actions/runs/34704176931/job/103581110552) then failed the independent pairing contract because the changed workflow blob `f315683208d57ba89a2942502c525abe7355e2fd` no longer matched the reviewed predecessor pin. Commit `683cb053b3c6f1c7b3f293a74263ac9b13e9bdf1` advances only that exact pin; no hash check is removed or relaxed.
- Hosted current-head tests, security, CodeQL, and independent review remain required. Only after ordinary protected-main integration may affected consumers rerun OpenCode; the predecessor run is never transferable as GREEN evidence.

## Follow-up

After merge, rerun only consumer failures whose cause changed, beginning with `contextual-orchestrator#1149`. Verify that the trusted image builds from the same `fast-mlsirm` commit, the PR sandbox remains networkless and credential-free, coverage/docstring evidence executes, and a substantive exact-head review is published. If any additional conventional source root is needed, add it through its own immutable fixture and one-root regression rather than generalized path discovery.
6 changes: 6 additions & 0 deletions docs/product-technical-gap-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@

이 문서는 제품·기술·운영 Gap을 현재 문서와 현재 GitHub 상태에 묶어 두는 기준선이다. 새 작업은 먼저 이 문서의 Gap ID를 PR 설명과 테스트 증거에 연결하고, PR의 정확한 exact HEAD·Checks·리뷰를 다시 수집한 뒤 구현한다. 표의 상태는 작성 시점의 관측값이므로, 병합 판단에는 재사용하지 않는다. 이 인벤토리는 스냅샷이며 merge authorization이 아니다.

### 2026-09-13 current-head incident delta

| Gap ID | 상태 | exact-head evidence | causal owner / next gate |
|---|---|---|---|
| CONTROL-OPENCODE-VCS-PYROOT-01 | **Proposed / source repaired; hosted exact-head validation pending** | `contextual-orchestrator#1149@684cf28f`의 중앙 [OpenCode run 34701472466](https://github.com/ContextualWisdomLab/.github/actions/runs/34701472466) `coverage-evidence` job `103574547257`은 PR 코드를 실행하기 전에 immutable `fast-mlsirm@09f762d`의 `python/fast_mlsirm` import root를 찾지 못해 종료했다. 같은 head의 제품 테스트는 `3602 passed, 2 skipped`, native CodeQL·fuzz·SBOM·SAST·Strix는 성공했다. | `.github`의 `opencode-review-dispatch.yml`이 root/`src/`만 허용한 계약 drift를 소유한다. RED contract `b1fe97c4`, 최소 source repair `af04581c`, exact workflow-blob trust pin `683cb053` 뒤, 이 문서 head의 integrated CI가 GREEN이고 protected `main`에 ordinary merge된 다음 affected consumer exact head를 다시 검증한다. |

## 1. 근거와 범위

### 1.1 우선순위가 높은 근거
Expand Down
4 changes: 4 additions & 0 deletions tests/test_opencode_agent_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,10 @@ def test_opencode_target_coverage_materializes_only_after_authorized_dispatch():
assert 'vcs-manifest.json >"$dependency_list"' in measure_step
assert 'done <"$dependency_list"' in measure_step
assert 'candidate_count=$((candidate_count + 1))' in measure_step
# Immutable VCS packages may expose their import package from a project-specific
# ``python/`` source root (fast-mlsirm is the live protected-base fixture).
assert '"$destination/python/$import_name"' in measure_step
assert '"$destination/python/$import_name.py"' in measure_step
assert '[ "$candidate_count" -ne 1 ]' in measure_step
assert "has a missing or ambiguous import root" in measure_step
assert '[ ! -f "$import_root/__init__.py" ]' in measure_step
Expand Down
2 changes: 1 addition & 1 deletion tests/test_pr_review_autofix_nvidia_nim_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
DOCTORING_RECORD = Path("docs/doctoring/hourly-nvidia-nim-autofix.md")
CHANGELOG = Path("CHANGELOG.md")
REVIEW_DISPATCH_WORKFLOW = Path(".github/workflows/opencode-review-dispatch.yml")
REVIEW_DISPATCH_BLOB_SHA = "d86497b3f43bebbabbb4f504eb5132cdf3b7b293"
REVIEW_DISPATCH_BLOB_SHA = "f315683208d57ba89a2942502c525abe7355e2fd"


def _workflow_text(path: Path) -> str:
Expand Down
Loading