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
1 change: 1 addition & 0 deletions ci-review-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ before deciding. Do not merely quote, summarize, or defer to the peer reviewer.
If you would otherwise approve but cannot source-back either a fix or a
false-positive dismissal for each plausible peer finding, request changes with
your own line-specific finding and verification direction.
When another review bot reports a plausible current-head static-analysis, linter, compiler, or accessibility defect, verify the claim independently before approving. For JSX/TSX and component templates, duplicate props such as repeated `aria-label`, repeated event handlers, or assignments overwritten later in the same element/object are blocking when they can mask the intended accessible name, event behavior, data binding, or runtime value. Do not approve by merely citing the peer bot; inspect the changed hunk or run the relevant parser/linter/typecheck in a scratch workspace, then either publish your own source-backed finding or explain the source-backed false-positive dismissal.

Review the diff first, then inspect surrounding code only when needed to
understand impact. Evaluate correctness, API compatibility, security/privacy,
Expand Down
1 change: 1 addition & 0 deletions code-reviewer-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ between PR intent, code, docs, tests, schemas, generated files, UI rendering,
and consumers. For changed scrolling, animation, transition, or motion behavior,
verify that `prefers-reduced-motion: reduce` users are not forced through smooth
scrolling or animated motion.
Treat peer review bot comments as adversarial seeds, not authority. If a peer bot flags a plausible current-head static-analysis, compiler, linter, or accessibility issue, independently verify it from the source hunk, parser/linter/typecheck output, runtime/library documentation, or a scratch repro before approving. In JSX/TSX and component templates, duplicate props such as repeated `aria-label`, repeated handlers, or assignments overwritten later in the same element/object are material defects when they can mask the intended accessible name, event behavior, data binding, or runtime value; report your own source-backed finding instead of merely quoting the peer bot.

Implementation completeness is mandatory. Inspect changed runtime code and
connected call sites for placeholder bodies such as `pass`, `...`,
Expand Down
55 changes: 52 additions & 3 deletions scripts/ci/run_opencode_review_model_pool.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,29 @@ backoff_sleep() {
printf '%s\n' "$sleep_for"
}

should_inline_prompt_evidence_excerpt() {
local model_candidate="$1"

# GitHub Models OpenAI review endpoints currently reject request bodies
# above roughly 4000 tokens. Keep full evidence available as workspace
# files, but do not inline the excerpt for those candidates.
case "$model_candidate" in
github-models/openai/gpt-5 | github-models/openai/gpt-5-chat | github-models/openai/o3)
return 1
;;
*)
return 0
;;
esac
}

write_prompt() {
local model_candidate="$1"
local prompt_file="$2"
local intro
local contract_file
local evidence_excerpt_file
local evidence_file_in_workdir

if [ -n "${OPENCODE_REVIEW_INTRO:-}" ]; then
intro="$OPENCODE_REVIEW_INTRO"
Expand All @@ -72,6 +89,7 @@ write_prompt() {
fi
contract_file="$OPENCODE_REVIEW_WORKDIR/opencode-review-contract-${model_candidate//\//-}.md"
evidence_excerpt_file="$OPENCODE_REVIEW_WORKDIR/bounded-review-evidence-excerpt.md"
evidence_file_in_workdir="$OPENCODE_REVIEW_WORKDIR/bounded-review-evidence.md"
cp "$GITHUB_WORKSPACE/scripts/ci/opencode_review_prompt_template.md" "$contract_file"
OPENCODE_REVIEW_INTRO="$intro" \
PROMPT_MODEL_CANDIDATE="$model_candidate" \
Expand All @@ -82,9 +100,17 @@ write_prompt() {
printf 'Follow the complete review contract in `%s`; use this launcher as a packet-first entry point, not as a reduced policy.\n' "$contract_file"
printf 'Read bounded review evidence from `%s` and source files from `%s` when tool access works.\n' "$OPENCODE_EVIDENCE_FILE" "$OPENCODE_SOURCE_WORKDIR"
printf 'Use the trusted review workspace `%s` for scripts, prompts, policy files, CodeGraph config, and validation helpers.\n\n' "$OPENCODE_REVIEW_WORKDIR"
printf 'First review the current-head evidence excerpt in this prompt. Then inspect full evidence, changed files, focused related code, and configured structural/search tools when available.\n'
if should_inline_prompt_evidence_excerpt "$model_candidate"; then
printf 'First review the current-head evidence excerpt in this prompt. Then inspect full evidence, changed files, focused related code, and configured structural/search tools when available.\n'
else
printf 'The current-head evidence excerpt is not inlined for this GitHub Models OpenAI candidate because that provider rejects large request bodies. First read `%s`, `%s`, changed files, focused related code, and configured structural/search tools before any conclusion.\n' "$evidence_file_in_workdir" "$evidence_excerpt_file"
fi
printf 'Never emit raw tool-call markup, MCP call syntax, function-call JSON, tool_call text, or a JSON array of tool calls. If tool calls or file reads are unavailable, do not emit progress notes or raw tool-call text.\n'
printf 'If full-file reads do not execute, use the inlined evidence packet and its repeated current-head sections for Changed files, Focused changed hunks, Coverage execution evidence, Failed GitHub Check evidence, and unresolved thread evidence.\n'
if should_inline_prompt_evidence_excerpt "$model_candidate"; then
printf 'If full-file reads do not execute, use the inlined evidence packet and its repeated current-head sections for Changed files, Focused changed hunks, Coverage execution evidence, Failed GitHub Check evidence, and unresolved thread evidence.\n'
else
printf 'If file reads do not execute for this non-inlined prompt, do not approve from memory or generic confidence. REQUEST_CHANGES only when the visible launcher text or executed file reads provide current-head evidence tied to a positive source/evidence line.\n'
fi
printf 'Do not request changes solely because your tool call, MCP call, or full-file read was not executed. Treat that as a review source limitation unless current-head evidence explicitly reports a materialization failure; any such finding must be tied to that evidence, not a generic model-exhaustion message. REQUEST_CHANGES findings must cite a positive source/evidence line; never use line 0.\n'
printf 'Always return a final control block instead of a progress summary. Return only the final review body.\n\n'
printf 'Required control block shape:\n'
Expand All @@ -93,7 +119,30 @@ write_prompt() {
printf '```\n'
if [ -s "$evidence_excerpt_file" ]; then
printf '\nCurrent-head evidence packet:\n\n'
cat "$evidence_excerpt_file"
if should_inline_prompt_evidence_excerpt "$model_candidate"; then
python3 - "$evidence_excerpt_file" "${OPENCODE_PROMPT_EVIDENCE_MAX_BYTES:-120000}" <<'PY'
import pathlib
import sys

path = pathlib.Path(sys.argv[1])
max_bytes = int(sys.argv[2])
data = path.read_bytes()
if len(data) <= max_bytes:
sys.stdout.buffer.write(data)
else:
head = data[: max_bytes // 2]
tail = data[-(max_bytes // 2) :]
sys.stdout.buffer.write(head)
sys.stdout.write(
"\n\n[OpenCode evidence excerpt truncated for provider context window; "
f"showing {len(head)} head bytes and {len(tail)} tail bytes from {len(data)} total bytes. "
"Read the full bounded-review-evidence.md file before making any source-backed conclusion.]\n\n"
)
sys.stdout.buffer.write(tail)
PY
else
printf '[Evidence excerpt omitted for `%s` to stay under the GitHub Models OpenAI request-body limit. Read `%s` and `%s` from the review workspace before returning a control block.]\n' "$model_candidate" "$evidence_file_in_workdir" "$evidence_excerpt_file"
fi
printf '\n'
fi
} >"$prompt_file"
Expand Down
51 changes: 50 additions & 1 deletion tests/test_opencode_model_pool_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ def run_failed_model(
*,
json_line: str = "",
stderr_line: str = "",
evidence_excerpt: str = "",
model_candidates: str = "github-models/openai/gpt-5",
prompt_capture: Path | None = None,
) -> subprocess.CompletedProcess[str]:
"""Run one fake provider failure through the real model-pool launcher."""
command = bash_command()
Expand All @@ -74,10 +77,18 @@ def run_failed_model(
shutil.copy2(ROOT / "opencode.jsonc", review_dir / "opencode.jsonc")
evidence_file = tmp_path / "evidence.md"
evidence_file.write_text("bounded current-head evidence\n", encoding="utf-8")
if evidence_excerpt:
(review_dir / "bounded-review-evidence-excerpt.md").write_text(
evidence_excerpt, encoding="utf-8"
)
(review_dir / "bounded-review-evidence.md").write_text(
f"full evidence\n{evidence_excerpt}", encoding="utf-8"
)
fake_opencode = fake_bin / "opencode"
fake_opencode.write_text(
"#!/usr/bin/env bash\n"
"if [ \"${1:-}\" = run ]; then\n"
" [ -z \"${FAKE_OPENCODE_PROMPT_CAPTURE:-}\" ] || printf '%s\\n' \"$2\" > \"$FAKE_OPENCODE_PROMPT_CAPTURE\"\n"
" [ -z \"${FAKE_OPENCODE_JSON:-}\" ] || printf '%s\\n' \"$FAKE_OPENCODE_JSON\"\n"
" [ -z \"${FAKE_OPENCODE_STDERR:-}\" ] || printf '%s\\n' \"$FAKE_OPENCODE_STDERR\" >&2\n"
" exit 1\n"
Expand All @@ -92,13 +103,14 @@ def run_failed_model(
env.update(
{
"FAKE_OPENCODE_JSON": json_line,
"FAKE_OPENCODE_PROMPT_CAPTURE": bash_path(prompt_capture) if prompt_capture else "",
"FAKE_OPENCODE_STDERR": stderr_line,
"GITHUB_OUTPUT": bash_path(github_output),
"GITHUB_WORKSPACE": bash_path(ROOT),
"HEAD_SHA": "1" * 40,
"OPENCODE_EVIDENCE_FILE": bash_path(evidence_file),
"OPENCODE_MODEL_ATTEMPTS": "1",
"OPENCODE_MODEL_CANDIDATES": "github-models/openai/gpt-5",
"OPENCODE_MODEL_CANDIDATES": model_candidates,
"OPENCODE_OUTPUT_FILE": bash_path(tmp_path / "selected-output.md"),
"OPENCODE_POOL_MAX_CYCLES": "1",
"OPENCODE_REVIEW_WORKDIR": bash_path(review_dir),
Expand Down Expand Up @@ -160,3 +172,40 @@ def test_failed_provider_without_reason_logs_explicit_absence(tmp_path: Path) ->
"OpenCode provider failure supplied no structured JSON or stderr reason "
"(json-bytes=0, stderr-bytes=0)."
) in result.stdout


def test_github_models_openai_prompt_references_evidence_without_inlining(tmp_path: Path) -> None:
"""Small-request GitHub Models OpenAI candidates keep evidence as files."""
prompt_capture = tmp_path / "captured-prompt.md"
evidence_excerpt = "UNIQUE_CURRENT_HEAD_EVIDENCE_PACKET"

result = run_failed_model(
tmp_path,
evidence_excerpt=evidence_excerpt,
prompt_capture=prompt_capture,
)

assert result.returncode == 1
prompt = prompt_capture.read_text(encoding="utf-8")
assert evidence_excerpt not in prompt
assert "Evidence excerpt omitted for `github-models/openai/gpt-5`" in prompt
assert "bounded-review-evidence.md" in prompt
assert "bounded-review-evidence-excerpt.md" in prompt


def test_deepseek_prompt_still_inlines_bounded_evidence_excerpt(tmp_path: Path) -> None:
"""Large-context DeepSeek candidates retain the current-head prompt packet."""
prompt_capture = tmp_path / "captured-prompt.md"
evidence_excerpt = "UNIQUE_DEEPSEEK_INLINE_EVIDENCE_PACKET"

result = run_failed_model(
tmp_path,
evidence_excerpt=evidence_excerpt,
model_candidates="github-models/deepseek/deepseek-v3-0324",
prompt_capture=prompt_capture,
)

assert result.returncode == 1
prompt = prompt_capture.read_text(encoding="utf-8")
assert evidence_excerpt in prompt
assert "Evidence excerpt omitted" not in prompt
Loading