Skip to content
Open
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
4 changes: 2 additions & 2 deletions .github/workflows/opencode-review-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,9 @@ jobs:
printf 'Authorized repository_dispatch actor=%s sender=%s target=%s.\n' "$DISPATCH_ACTOR" "$DISPATCH_SENDER" "$TARGET_REPOSITORY"
fi

if ! [[ "$TARGET_REPOSITORY" =~ ^ContextualWisdomLab/[A-Za-z0-9_.-]+$ ]] ||
if ! [[ "$TARGET_REPOSITORY" =~ ^(ContextualWisdomLab/[A-Za-z0-9_.-]+|HYOSUNG-ITX-AI-Business-Department/llm-gateway-console(-design)?)$ ]] ||
! [[ "$PR_NUMBER" =~ ^[1-9][0-9]*$ ]]; then
printf '::error::PR metadata validation rejected a target outside ContextualWisdomLab or an invalid pull request number. target=%s pr=%s\n' "${TARGET_REPOSITORY:-<empty>}" "${PR_NUMBER:-<empty>}"
printf '::error::PR metadata validation rejected a target outside the approved consumer scope or an invalid pull request number. target=%s pr=%s\n' "${TARGET_REPOSITORY:-<empty>}" "${PR_NUMBER:-<empty>}"
exit 1
fi

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/opencode-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ jobs:
run: |
set -euo pipefail
echo "admitted=false" >>"$GITHUB_OUTPUT"
if ! [[ "$TARGET_REPOSITORY" =~ ^ContextualWisdomLab/[A-Za-z0-9_.-]+$ ]] ||
if ! [[ "$TARGET_REPOSITORY" =~ ^(ContextualWisdomLab/[A-Za-z0-9_.-]+|HYOSUNG-ITX-AI-Business-Department/llm-gateway-console(-design)?)$ ]] ||
! [[ "$PR_NUMBER" =~ ^[1-9][0-9]*$ ]] ||
! [[ "$EXPECTED_HEAD_SHA" =~ ^[0-9a-f]{40}$ ]]; then
echo "::error::OpenCode admission rejected malformed pull request metadata."
Expand Down
63 changes: 63 additions & 0 deletions docs/doctoring/hyosung-opencode-consumer-admission.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Hyosung OpenCode intake candidate

Status: Proposed. Base: fb17ef556f94f673234aa557254ae52779e9a7b0.

MLLO console and its design owner cannot use the canonical OpenCode intake:
the required caller and dispatch receiver reject their organization even when
the exact repository is configured in the dispatch allowlist. Four extracted
intake tests failed on the base. This candidate admits only
`HYOSUNG-ITX-AI-Business-Department/llm-gateway-console` and
`HYOSUNG-ITX-AI-Business-Department/llm-gateway-console-design`.

The existing dispatch actor and sender must still match the same configured
identity. An empty or missing live target allowlist remains denied. Live PR
base/head, visibility and state checks remain authoritative. OIDC exchange,
metadata access, private-target ZDR, review publication identity and separate
status permissions are unchanged. The canonical workflow continues to use its
existing CO free route; no paid route or consumer workflow copy is introduced.

## Remaining deployment prerequisites

The JSON target inventory is a proposed configuration delta, not evidence that
the live repository variable changed. After protected owner review and merge,
reconcile the live variable without dropping concurrent entries. This candidate
does not change any GitHub variable or installation permission.

Before consumer adoption, establish the OIDC-exchanged App identity can read each
private target and its live PR metadata; separately verify review publication and
status-write authority. A repository name match cannot prove any of those
capabilities. Verify one exact-head dispatch per consumer, matching private
visibility and immutable source/base/head, followed by an actual formal review
and required status. Missing App access must fail closed rather than widening
installation scope or substituting an unverified credential. Current tests use
local extracted guards and do not establish cross-organization runtime access.

The organization scheduler/mention router retain their existing CWL-only scope;
this candidate enables the required-caller/direct authenticated-dispatch path,
not an unverified cross-organization scheduler rollout. Consumer installation of
the reviewed workflow contract remains separate work. Existing edge policy also
remains active; any policy conflict requires an explicit owner decision, not a
bypass in this admission change.

Local validation: 128 passed, 1 skipped across intake, agent contract, Rust
coverage pin, live-Draft and required-verdict regressions under
`GITHUB_ACTIONS=true`. The dispatch content hash was recomputed with
`git hash-object`; no action/version pin was substituted. Hosted verification
and actual permission evidence remain outstanding.

## Local lint process diagnosis

Homebrew actionlint 1.7.12 blocked before starting ShellCheck on macOS. Its
upstream `process.go` writes the entire script into `StdinPipe` before calling
`Output`; scripts exceeding the pipe capacity deadlock. PID 35499 had no child
processes and its SIGQUIT dump showed two writes blocked with 130814 and 67165
byte inputs. The process was terminated diagnostically, not treated as success.

Official tag v1.7.12 (914e7df21a07ef503a81201c76d2b11c789d3fca) was cloned into
an isolated temporary directory. Replacing only that pipe write with
`cmd.Stdin = strings.NewReader(e.stdin)` allowed full lint to finish; upstream
`TestProcess` tests passed. No installed binary or workflow gate was changed.
Native actionlint with ShellCheck disabled passed workflow validation. Full
repaired-tool lint remained nonzero: its output exactly matched the clean
fb17ef556 baseline, with no admission-delta findings. These existing ShellCheck
findings remain unresolved and must not be reported as full lint success.
4 changes: 3 additions & 1 deletion scripts/ci/opencode_repository_dispatch_targets.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
"ContextualWisdomLab/semantic-data-portal",
"ContextualWisdomLab/wardnet",
"ContextualWisdomLab/xtrm-lead-pi-outbound",
"ContextualWisdomLab/xtrmLLMBatchPython"
"ContextualWisdomLab/xtrmLLMBatchPython",
"HYOSUNG-ITX-AI-Business-Department/llm-gateway-console",
"HYOSUNG-ITX-AI-Business-Department/llm-gateway-console-design"
]
}
2 changes: 1 addition & 1 deletion tests/test_opencode_agent_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -2760,7 +2760,7 @@ def test_opencode_strix_security_regressions_are_closed():
config = load_opencode_jsonc()

assert " validate-pr-metadata:\n" in workflow
assert "^ContextualWisdomLab/[A-Za-z0-9_.-]+$" in workflow
assert "^(ContextualWisdomLab/[A-Za-z0-9_.-]+|HYOSUNG-ITX-AI-Business-Department/llm-gateway-console(-design)?)$" in workflow
assert (
"repository_dispatch metadata does not match the live pull request" in workflow
)
Expand Down
33 changes: 33 additions & 0 deletions tests/test_opencode_hyosung_repository_admission.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Execute canonical intake guards for the two exact MLLO owners."""

import os
from pathlib import Path
import re
import subprocess
import textwrap

import pytest


@pytest.mark.parametrize("suffix", ["", "-design"])
def test_hyosung_intake_preserves_dispatch_authority(suffix):
"""Exact scope cannot replace matching dispatcher identity and live metadata."""
target = "HYOSUNG-ITX-AI-Business-Department/llm-gateway-console" + suffix
workflow = Path(".github/workflows/opencode-review-dispatch.yml").read_text()
section = workflow.split(" - name: Bind workflow inputs to live organization pull request metadata\n", 1)[1]
program = textwrap.dedent(section.split(" run: |\n", 1)[1].split(" pull_request_json=", 1)[0])
env = dict(os.environ, EVENT_NAME="repository_dispatch", DISPATCH_ACTOR="opencode-agent[bot]", DISPATCH_SENDER="opencode-agent[bot]", ALLOWED_DISPATCH_ACTOR="opencode-agent[bot]", ALLOWED_DISPATCH_TARGETS=target, TARGET_REPOSITORY=target, PR_NUMBER="1")
for overrides, expected in (({}, 0), ({"DISPATCH_SENDER": "forged"}, 1), ({"ALLOWED_DISPATCH_TARGETS": ""}, 1), ({"PR_NUMBER": "0"}, 1)):
result = subprocess.run(["bash", "-c", program], env={**env, **overrides}, capture_output=True, text=True)
assert result.returncode == expected, result.stdout


@pytest.mark.parametrize("filename", ["opencode-review.yml", "opencode-review-dispatch.yml"])
def test_only_exact_hyosung_names_pass(filename):
"""Both guards reject near names even if the external allowlist lists them."""
source = Path(".github/workflows", filename).read_text()
pattern, = re.findall(r'"\$TARGET_REPOSITORY" =~ (\^[^ ]+)', source)
owner = "HYOSUNG-ITX-AI-Business-Department/llm-gateway-console"
for target, accepted in ((owner, True), (owner + "-design", True), (owner + "-extra", False), (owner + "-design-extra", False), (owner + "/extra", False), (owner + "\n", False), ("other/llm-gateway-console", False)):
result = subprocess.run(["bash", "-c", '[[ "$TARGET_REPOSITORY" =~ ' + pattern + ' ]]'], env=dict(os.environ, TARGET_REPOSITORY=target), capture_output=True)
assert (result.returncode == 0) == accepted
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 = "8b42e279fb3a9890eaf80000926f403fbc2f1807"


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