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
14 changes: 14 additions & 0 deletions docs/doctoring/contextual-orchestrator-vendored-sidecar.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,17 @@ training (OpenRouter's own stance). Evidence sources:
`tests/test_pr_review_autofix_writer_security_contract.py`,
`tests/test_noema_review_gate.py`,
`docs/doctoring/noema-orchestrator-free-zdr.md`.

## 2026-08-28 runtime correction

The first post-merge Strix execution (`33139957477`) failed before serving: the
pinned orchestrator's `load_agents()` indexes the top-level `agents` field, but
the launcher persisted only the list value. Follow-up PR [#1370](https://github.com/ContextualWisdomLab/.github/pull/1370)
wraps both the launcher output and the standalone policy builder output in the
loader-compatible `{"agents": [...]}` envelope. The regression is covered by
`tests/test_contextual_orchestrator_review_policy.py` and the sidecar contract;
the full local suite passed with `1689 passed, 1 skipped, 16 subtests passed`.

The PR-target Noema check still runs the trusted base copy until this trusted
workflow change is merged, so its reproduction of the old error is retained as
bootstrap evidence rather than treated as a current-head runtime result.
34 changes: 31 additions & 3 deletions docs/product-technical-gap-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,37 @@ flowchart LR
`zdr_policy.py`, `contextual_orchestrator_review_policy.py`,
`contextual_orchestrator_review_launcher.py`; records
`docs/adr/0003-…`, `docs/doctoring/contextual-orchestrator-vendored-sidecar.md`.
- Remaining (follow-up loops): read-only dispatch pool, `noema-review.yml`,
and `strix.yml` still use pinned direct-provider pools; ZDR feed integration
in the standard opencode pool and runner-side egress attestation per stage.
- At the time of this 2026-08-27 snapshot, the remaining follow-up was the
read-only dispatch pool, `noema-review.yml`, and `strix.yml` migration. This
historical observation is superseded by the current-main evidence below.

## 2026-08-28 current-main routing and runtime recheck

- Current protected-main candidate is `f8823a544c3c4c046977f8511f683e85f83eb496`,
the merge commit for #1364. #1360 is merged at
`17052a7ca3c16db90932a4d6036b43165ddee418`.
- The current Required OpenCode dispatch, `noema-review.yml`, `strix.yml`,
and write-capable `pr-review-autofix.yml` all provision the pinned
`contextual-orchestrator` sidecar. Their model route is the
`contextual-orchestrator/orchestrator/free` gateway, with the five provider
secrets entering the sidecar KV and model discovery performed there. No
`COPILOT_GITHUB_TOKEN` route is present.
- #1364 was merged by `seonghobae` while its terminal review decision remained
`CHANGES_REQUESTED`; this is an observed merge event, not protected-main
governance evidence. The required branch checks still include
`noema-review` and `opencode-review`.
- Post-merge Strix run `33139957477` exposed a real sidecar runtime defect:
`contextual_orchestrator.orchestrator.load_agents()` requires an
`{"agents": [...]}` catalog envelope, while the launcher wrote a bare list.
Follow-up #1370 fixes the launcher and the standalone policy catalog writer
in commit `861463c11a7ca8b1f9179073e2a3db9eba5aa5ab`; its current head is
`38e0307c655823a1e474b29aae89f8cfcb1edbc0`. Focused tests and the full local
suite pass (`1689 passed, 1 skipped, 16 subtests passed`).
- #1370 remains open and blocked against main `f8823a5`. Its PR-target Noema
run `33140830199` executes the trusted base launcher and reproduces the
pre-fix bare-list error; its `opencode-review` check fails closed because no
current-head OpenCode verdict exists. These are bootstrap evidence gaps,
not proof that the #1370 catalog-envelope patch fails.

## 5. 실행 루프와 고객의 다음 행동

Expand Down
4 changes: 2 additions & 2 deletions scripts/ci/contextual_orchestrator_review_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def main(argv: list[str] | None = None) -> int:
require_zdr=args.require_zdr,
)
Path(args.catalog_out).write_text(
json.dumps(result["agents"], indent=2) + "\n", encoding="utf-8"
json.dumps({"agents": result["agents"]}, indent=2) + "\n", encoding="utf-8"
Comment thread
seonghobae marked this conversation as resolved.
)
Path(args.report_out).write_text(
json.dumps(result["report"], indent=2) + "\n", encoding="utf-8"
Comment thread
seonghobae marked this conversation as resolved.
Expand All @@ -163,4 +163,4 @@ def main(argv: list[str] | None = None) -> int:


if __name__ == "__main__": # pragma: no cover
raise SystemExit(main())
raise SystemExit(main())
6 changes: 4 additions & 2 deletions scripts/ci/contextual_orchestrator_review_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,9 @@ def build_catalog_from_paths(
zdr_endpoints=zdr_endpoints,
require_zdr=require_zdr,
)
Path(out_path).write_text(json.dumps(result["agents"], indent=2) + "\n", encoding="utf-8")
Path(out_path).write_text(
json.dumps({"agents": result["agents"]}, indent=2) + "\n", encoding="utf-8"
)
Path(report_path).write_text(json.dumps(result["report"], indent=2) + "\n", encoding="utf-8")
return result

Expand Down Expand Up @@ -384,4 +386,4 @@ def main(argv: list[str] | None = None) -> int:


if __name__ == "__main__": # pragma: no cover
raise SystemExit(main())
raise SystemExit(main())
2 changes: 1 addition & 1 deletion tests/test_contextual_orchestrator_review_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ def test_build_catalog_from_paths_writes_both_files(tmp_path) -> None:
)
assert catalog.exists()
assert report.exists()
assert result["agents"] == json.loads(catalog.read_text(encoding="utf-8"))
assert {"agents": result["agents"]} == json.loads(catalog.read_text(encoding="utf-8"))
assert result["report"] == json.loads(report.read_text(encoding="utf-8"))


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ def test_launcher_uses_orchestrator_discovery_and_free_pool() -> None:
assert "from scripts.ci import zdr_policy" in text


def test_launcher_wraps_catalog_for_vendored_load_agents() -> None:
"""Persist the catalog envelope expected by the pinned orchestrator loader."""
text = _read(LAUNCHER)
assert 'json.dumps({"agents": result["agents"]}' in text
assert 'json.dumps(result["agents"]' not in text


def test_launcher_requires_gateway_token_and_a_provider_credential() -> None:
"""The sidecar never boots without an auth token and a provider credential."""
text = _read(LAUNCHER)
Expand Down
Loading