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
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@ this file. The format follows Keep a Changelog, and versioned releases follow
Semantic Versioning where the repository publishes a release.

## [Unreleased]
- Fix a broken CI contract test that was blocking every open `.github`-repo
PR: `test_strix_quick_gate.sh`'s
`assert_opencode_review_uses_codegraph_and_contextual_orchestrator` used an
`awk '/^ required-workflow-bootstrap:$/,/^[^ ]/'` range to isolate that
one job's YAML block in `opencode-review.yml`, intending to assert it has
no `if:` condition on any step (a real trust-boundary invariant: this
bootstrap job must never depend on event-payload fields). Because job keys
in that file are always 2-space indented, `/^[^ ]/` (a truly unindented
line) never matches anywhere in the `jobs:` section, so the range never
closed and silently swallowed every job defined after
`required-workflow-bootstrap` too — including the unrelated,
legitimate `if: github.event.action != 'closed'` on a completely different
job's step. `required-workflow-bootstrap` itself has always had zero `if:`
conditions; only the test's own job-scoping was wrong. Replaced the range
with an explicit awk state machine that starts at the bootstrap job header
and stops at the next 2-space-indented job key, so it correctly isolates
only that job's steps.
- Harden the review sidecar's per-account catalog cap against silent drift:
`contextual_orchestrator_review_launcher.py`'s two
`build_zdr_prioritized_catalog` call sites now source their
Expand Down
9 changes: 9 additions & 0 deletions scripts/ci/noema_review_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@
"opencode-agent",
}
GITHUB_APP_BOT_RE = re.compile(r"^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\[bot\]$")
# Wraps the start of the fixed-format footer submit_review() writes below the
# LLM-generated summary/findings text. This lets noema_review_handoff.py
# locate the footer by *position* (the trusted, machine-emitted span between
# this marker and the closing "<!-- noema-review-gate head_sha=... -->"
# comment) instead of by scanning for a content pattern that the LLM's own
# unsanitized output could coincidentally reproduce. Keep this literal in
# exact sync with NOEMA_REVIEW_FOOTER_MARKER in noema_review_handoff.py.
NOEMA_REVIEW_FOOTER_MARKER = "<!-- noema-review-gate-footer -->"
MAX_DIFF_CHARS = 60000
MAX_CONTEXT_FILES = 12
MAX_FILE_CONTEXT_CHARS = 4000
Expand Down Expand Up @@ -759,6 +767,7 @@ def submit_review(repo: str, number: int, pr: dict[str, Any], actor: str, verdic
"### Findings",
*(findings or ["- No blocking findings."]),
"",
NOEMA_REVIEW_FOOTER_MARKER,
f"- Result: {event}",
f"- Head SHA: `{head_sha}`",
f"- Reviewer credential: `{source}`",
Expand Down
76 changes: 73 additions & 3 deletions scripts/ci/noema_review_handoff.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@
NOEMA_REVIEW_AUTHOR = "cwl-noema-review[bot]"
NOEMA_REVIEW_MARKER = "<!-- noema-review-gate "
NOEMA_MARKER_HEAD_RE = re.compile(r"<!-- noema-review-gate head_sha=([0-9a-fA-F]{40}) decision=[a-z_]+ -->")
NOEMA_BODY_HEAD_RE = re.compile(r"Head SHA:\s*`([0-9a-fA-F]{40})`")
# Must stay byte-for-byte identical to NOEMA_REVIEW_FOOTER_MARKER in
# noema_review_gate.py's submit_review(). See _isolate_trusted_footer() for
# why this positional bound exists.
NOEMA_REVIEW_FOOTER_MARKER = "<!-- noema-review-gate-footer -->"
# Matches only the literal footer bullet submit_review() writes
# ("- Head SHA: `<sha>`", one full line via re.MULTILINE, nothing else). This
# is deliberately *not* the sole defense — see _isolate_trusted_footer().
NOEMA_BODY_HEAD_RE = re.compile(r"^- Head SHA:\s*`([0-9a-fA-F]{40})`$", re.MULTILINE)
TERMINAL_NOEMA_STATES = {"APPROVED", "CHANGES_REQUESTED", "COMMENTED"}


Expand Down Expand Up @@ -95,6 +102,67 @@ def fetch_reviews(
return flatten_reviews(document)


def _isolate_trusted_footer(body: str) -> str:
"""Return the machine-emitted footer span of a Noema review body.

submit_review() writes its fixed-format footer (the ``Result`` /
``Head SHA`` / ``Reviewer credential`` / ``Actor`` bullets) in one
specific position: after ``NOEMA_REVIEW_FOOTER_MARKER`` and before the
closing ``<!-- noema-review-gate head_sha=... -->`` comment. Everything
else in the body — the summary and findings the LLM itself generates —
is unsanitized and can in principle contain a line that merely
*resembles* a footer bullet (a standalone ``- Head SHA: `<sha>``` line
included in prose, for instance, which an earlier version of this
extraction only excluded when it did not fall on its own line, and did
not exclude at all before that). Locating the footer by *position*
between the two trusted, machine-emitted delimiters — rather than by
scanning the whole body for a content pattern the LLM's own output could
reproduce, deliberately or by coincidence — removes that class of
collision entirely: LLM text can never land inside a span bounded on
both sides by markers only ``submit_review()`` emits.

Returns an empty string when the footer marker cannot be found (for
example, a review body posted before this marker existed), which causes
the caller's exact-one-match check to fail closed rather than fall back
to scanning untrusted text.
"""
before_end_marker = body.rsplit(NOEMA_REVIEW_MARKER, 1)[0]
parts = before_end_marker.rsplit(NOEMA_REVIEW_FOOTER_MARKER, 1)
return parts[1] if len(parts) == 2 else ""


def _isolate_trusted_marker_tail(body: str) -> str:
"""Return the machine-emitted tail of a Noema review body, footer onward.

``submit_review()``'s ``"\\n".join([...])`` writes ``NOEMA_REVIEW_FOOTER_MARKER``
immediately before its fixed-format footer bullets, and the closing
``<!-- noema-review-gate head_sha=... decision=... -->`` comment is
unconditionally the *last* element of that join — nothing follows it.
So, just like the span ``_isolate_trusted_footer()`` extracts, everything
from the footer marker to the end of the body is exclusively
machine-emitted text the LLM's own summary/findings prose can never
reach.

``noema_review_state()`` used to run ``NOEMA_MARKER_HEAD_RE`` over the
raw, unsanitized ``body`` to find the closing marker — the marker-side
counterpart of the body-side gap ``_isolate_trusted_footer()`` was added
to close. An LLM can, in principle, generate a complete,
correctly-formatted ``<!-- noema-review-gate head_sha=... decision=...
-->``-shaped string of its own (for instance while discussing this exact
review format) anywhere in its free-form prose *before* the real footer.
Searching this trusted tail instead removes that string from
consideration entirely, the same way position-anchoring already does for
the body-side bullet.

Returns an empty string when the footer marker cannot be found (for
example, a review body posted before this marker existed), which causes
the caller's exact-one-match check to fail closed, matching
``_isolate_trusted_footer()``'s own behavior.
"""
parts = body.rsplit(NOEMA_REVIEW_FOOTER_MARKER, 1)
return parts[1] if len(parts) == 2 else ""


def noema_review_state(reviews: list[dict[str, Any]], head_sha: str) -> str | None:
"""Return Noema's latest terminal verdict for the exact current head."""
for review in reversed(reviews):
Expand All @@ -106,8 +174,10 @@ def noema_review_state(reviews: list[dict[str, Any]], head_sha: str) -> str | No
if NOEMA_REVIEW_MARKER not in str(review.get("body") or ""):
continue
body = str(review.get("body") or "")
marker_heads = NOEMA_MARKER_HEAD_RE.findall(body)
body_heads = NOEMA_BODY_HEAD_RE.findall(body)
marker_tail = _isolate_trusted_marker_tail(body)
marker_heads = NOEMA_MARKER_HEAD_RE.findall(marker_tail)
footer_text = _isolate_trusted_footer(body)
Comment thread
seonghobae marked this conversation as resolved.
body_heads = NOEMA_BODY_HEAD_RE.findall(footer_text)
if len(marker_heads) != 1 or len(body_heads) != 1:
continue
if marker_heads[0].lower() != head_sha.lower() or body_heads[0].lower() != head_sha.lower():
Expand Down
6 changes: 5 additions & 1 deletion scripts/ci/test_strix_quick_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,11 @@ assert_opencode_review_uses_codegraph_and_contextual_orchestrator() {
assert_file_not_contains "$workflow_file" "Wait for trusted OpenCode approval review" "opencode pull_request bridge was removed to avoid duplicate required-check resource use"
assert_file_not_contains "$workflow_file" "Trusted OpenCode requested changes for head" "opencode pull_request bridge no longer reconsumes stale trusted review state"
assert_file_not_contains "$workflow_file" "github.event.pull_request.number == 240" "opencode review workflow must not hard-code repository-specific PR bypasses"
if awk '/^ required-workflow-bootstrap:$/,/^[^ ]/' "$bootstrap_file" | grep -q '^[[:space:]]*if:'; then
if awk '
/^ required-workflow-bootstrap:$/ { in_job = 1; print; next }
in_job && /^ [A-Za-z0-9_-]+:$/ { exit }
in_job { print }
' "$bootstrap_file" | grep -q '^[[:space:]]*if:'; then
Comment thread
seonghobae marked this conversation as resolved.
record_failure "opencode required workflow bootstrap must not depend on required-workflow event payload fields"
fi
assert_file_contains "$workflow_file" 'github.event.client_payload.target_repository || github.repository' "opencode review scopes concurrency by target repository"
Expand Down
Loading
Loading