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: 4 additions & 0 deletions .github/workflows/noema-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ jobs:
|| (
github.event_name == 'workflow_run'
&& github.event.workflow_run.conclusion != 'cancelled'
&& (
github.event.workflow_run.path == '.github/workflows/opencode-review.yml'
|| github.event.workflow_run.path == '.github/workflows/strix.yml'
)
)
|| (
github.event_name == 'pull_request_target'
Expand Down
35 changes: 26 additions & 9 deletions .github/workflows/opencode-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2528,7 +2528,7 @@ jobs:
fi
printf -- "- Merge base SHA: \`%s\`\n\n" "$PR_MERGE_BASE"
printf '## Current-head authority order\n\n'
printf 'Treat current-head sections in this file as authoritative for this run: Other unresolved review thread evidence, Failed GitHub Check evidence, Coverage execution evidence, Changed files, and Focused changed hunks.\n'
printf 'Treat current-head sections in this file as authoritative for this run: Other unresolved review thread evidence, Failed GitHub Check evidence, Coverage execution evidence, Changed files, Focused changed hunks, and Trusted changed-line source receipts.\n'
printf 'All PR reviews and comments evidence is historical context only and may contain stale bot conclusions. Do not infer active failed checks, unresolved threads, or missing changed files from those comments unless current-head evidence corroborates the same claim for Head SHA `%s`.\n\n' "$PR_HEAD_SHA"
if ! git -C "$OPENCODE_SOURCE_WORKDIR" diff --name-only --find-renames "$PR_MERGE_BASE" "$PR_HEAD_SHA" |
awk 'NF > 0 && $0 !~ /^\// && $0 !~ /(^|\/)\.\.($|\/)/ { print }' >"$OPENCODE_CHANGED_FILES_FILE"; then
Expand Down Expand Up @@ -2609,6 +2609,18 @@ jobs:
fi
printf '\n```\n'

printf '\n## Trusted changed-line source receipts\n\n'
if python3 "$GITHUB_WORKSPACE/scripts/ci/opencode_source_line_receipts.py" \
--repo-root "$OPENCODE_SOURCE_WORKDIR" \
--diff-base "$PR_MERGE_BASE" \
--head-sha "$PR_HEAD_SHA" \
--changed-files "$OPENCODE_CHANGED_FILES_FILE"; then
printf '\n'
else
printf 'Trusted changed-line source receipt generation failed; approval evidence is incomplete.\n' >&2
exit 1
fi

printf '\n## Review inspection contract\n\n'
printf 'Use the local checkout for exact source and diff inspection.\n'
printf 'Do not run a broad full-diff read into the model context; inspect changed files and focused hunks only.\n'
Expand Down Expand Up @@ -2719,6 +2731,7 @@ jobs:
append_evidence_section "Coverage execution evidence" 7000
append_evidence_section "Changed files" 7000
append_evidence_section "Focused changed hunks" 14000
append_evidence_section "Trusted changed-line source receipts" 12000
printf '\n\n[Full evidence is available in ./bounded-review-evidence.md inside the isolated review workspace.]\n'
} >"$OPENCODE_REVIEW_WORKDIR/bounded-review-evidence-excerpt.md"
fi
Expand Down Expand Up @@ -7409,20 +7422,24 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
# repository_dispatch requires Contents write. The job token is selected
# only when this run already executes in the central workflow repository;
# required-workflow runs in target repositories still need an explicitly
# configured cross-repository credential.
contents: write
pull-requests: read
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
steps:
- name: Dispatch deferred same-head review retry after model-pool exhaustion
env:
GH_TOKEN: ${{ github.token }}
# Cross-repository dispatch of the central workflow needs a PAT; the
# target-repository runner token cannot dispatch workflows that live
# in the central .github repository, and the OpenCode app token has
# no Actions permission.
RETRY_DISPATCH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN }}
RETRY_DISPATCH_TOKEN_SOURCE: ${{ secrets.PR_REVIEW_MERGE_TOKEN != '' && 'PR_REVIEW_MERGE_TOKEN' || secrets.OPENCODE_APPROVE_TOKEN != '' && 'OPENCODE_APPROVE_TOKEN' || 'none' }}
# A run already executing in the central repository can use its
# least-scoped job token. Cross-repository required-workflow runs
# still need a PAT because their target-repository job token cannot
# dispatch an event into ContextualWisdomLab/.github.
RETRY_DISPATCH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN || (github.repository == 'ContextualWisdomLab/.github' && github.token) }}
RETRY_DISPATCH_TOKEN_SOURCE: ${{ secrets.PR_REVIEW_MERGE_TOKEN != '' && 'PR_REVIEW_MERGE_TOKEN' || secrets.OPENCODE_APPROVE_TOKEN != '' && 'OPENCODE_APPROVE_TOKEN' || github.repository == 'ContextualWisdomLab/.github' && 'current-repository-job-token' || 'none' }}
# One fixed backoff window before the single deferred retry. GitHub
# Models per-minute throttles recover well inside this window; daily
# quota exhaustion outlives any in-workflow delay and is the org
Expand All @@ -7437,7 +7454,7 @@ jobs:
run: |
set -euo pipefail
if [ -z "${RETRY_DISPATCH_TOKEN:-}" ]; then
echo "::warning::Deferred exhausted-pool retry skipped because no cross-repository dispatch credential (PR_REVIEW_MERGE_TOKEN or OPENCODE_APPROVE_TOKEN) is configured; the merge scheduler org sweep remains the retry path."
echo "::warning::Deferred exhausted-pool retry skipped because this is not the central workflow repository and no cross-repository dispatch credential (PR_REVIEW_MERGE_TOKEN or OPENCODE_APPROVE_TOKEN) is configured; the merge scheduler org sweep remains the retry path."
exit 0
fi

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/pr-review-merge-scheduler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ jobs:
github.event_name != 'workflow_run' ||
(
github.event.workflow_run.conclusion != 'cancelled' &&
(
github.event.workflow_run.path == '.github/workflows/opencode-review.yml' ||
github.event.workflow_run.path == '.github/workflows/strix.yml'
) &&
github.event.workflow_run.pull_requests[0].number
)
) &&
Expand Down
92 changes: 92 additions & 0 deletions .github/workflows/strix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,13 @@ jobs:
test -f "$trusted_strix_source/scripts/ci/strix_quick_gate.sh"
test -f "$trusted_strix_source/scripts/ci/test_strix_quick_gate.sh"
test -f "$trusted_strix_source/scripts/ci/strix_required_workflow_smoke.sh"
test -f "$trusted_strix_source/scripts/ci/strix_emit_appguardrail_issues.py"
{
echo "TRUSTED_STRIX_SOURCE=$trusted_strix_source"
echo "TRUSTED_STRIX_GATE=$trusted_strix_source/scripts/ci/strix_quick_gate.sh"
echo "TRUSTED_STRIX_GATE_TEST=$trusted_strix_source/scripts/ci/test_strix_quick_gate.sh"
echo "TRUSTED_STRIX_REQUIRED_SMOKE=$trusted_strix_source/scripts/ci/strix_required_workflow_smoke.sh"
echo "TRUSTED_STRIX_ISSUE_EMITTER=$trusted_strix_source/scripts/ci/strix_emit_appguardrail_issues.py"
} >> "$GITHUB_ENV"

- name: Exchange OpenCode app token for target repository reads
Expand Down Expand Up @@ -652,6 +654,7 @@ jobs:
echo "STRIX_LLM_FILE=$strix_llm_file" >> "$GITHUB_ENV"

- name: Run Strix (quick)
id: run_strix
if: steps.gate.outputs.enabled == 'true'
timeout-minutes: 30
# Security invariant for pull_request_target: execute only from the
Expand Down Expand Up @@ -721,13 +724,15 @@ jobs:
set -e

if [ "$strix_rc" -eq 0 ]; then
echo "scan_complete=true" >> "$GITHUB_OUTPUT"
exit 0
fi

# Preserve configuration failures (exit 2) and any unexpected exit
# code as hard failures — only the scan-failure code (1) can be an
# infrastructure/backend-unavailability outcome.
if [ "$strix_rc" -ne 1 ]; then
echo "scan_complete=false" >> "$GITHUB_OUTPUT"
exit "$strix_rc"
fi

Expand All @@ -746,9 +751,11 @@ jobs:
if grep -Eiq "$backend_unavailable_signal" "$strix_run_log" \
&& ! grep -Eiq "$reported_vulnerability_signal" "$strix_run_log"; then
echo "::warning title=Strix backend unavailable::Strix could not complete because its LLM backend was unavailable (rate limit / token cap / connection or warm-up failure) before producing a vulnerability report. Treating as a neutral skip so an infrastructure outage does not block merges; genuine findings still fail the check. See the strix-reports artifact and the run log."
echo "scan_complete=false" >> "$GITHUB_OUTPUT"
exit 0
fi

echo "scan_complete=false" >> "$GITHUB_OUTPUT"
echo "Strix reported security findings or failed for a non-backend reason; failing the required check (gate exit ${strix_rc})." >&2
exit "$strix_rc"

Expand Down Expand Up @@ -787,6 +794,91 @@ jobs:
if-no-files-found: error
retention-days: 5

- name: Validate AppGuardrail issue emitter credential
if: ${{ always() && !cancelled() && steps.gate.outputs.enabled == 'true' }}
id: appguardrail_issue_credential
env:
NOEMA_GITHUB_APP_CLIENT_ID: ${{ vars.NOEMA_GITHUB_APP_CLIENT_ID || '' }}
NOEMA_GITHUB_APP_PRIVATE_KEY: ${{ secrets.NOEMA_GITHUB_APP_PRIVATE_KEY || '' }}
run: |
set -euo pipefail
if [ -z "${NOEMA_GITHUB_APP_CLIENT_ID:-}" ] || [ -z "${NOEMA_GITHUB_APP_PRIVATE_KEY:-}" ]; then
echo "::error::AppGuardrail issue collection is unconfigured: NOEMA_GITHUB_APP_CLIENT_ID and NOEMA_GITHUB_APP_PRIVATE_KEY are both required. Findings cannot be silently dropped."
exit 1
fi
echo "::notice::AppGuardrail issue collection will use a repository-scoped cwl-noema-review installation token."

- name: Mint AppGuardrail-scoped Noema GitHub App token
if: ${{ always() && !cancelled() && steps.gate.outputs.enabled == 'true' && steps.appguardrail_issue_credential.outcome == 'success' }}
id: noema_issue_token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.NOEMA_GITHUB_APP_CLIENT_ID }}
private-key: ${{ secrets.NOEMA_GITHUB_APP_PRIVATE_KEY }}
owner: ContextualWisdomLab
repositories: appguardrail
permission-issues: write
permission-metadata: read

- name: Resolve source repository for Code Scanning
if: ${{ always() && !cancelled() && steps.gate.outputs.enabled == 'true' && steps.appguardrail_issue_credential.outcome == 'success' }}
id: code_scanning_source
env:
SOURCE_REPO: ${{ github.event.pull_request.base.repo.full_name || github.event.client_payload.target_repository || github.repository }}
run: |
set -euo pipefail
python3 - <<'PY'
import os
import re

source_repo = os.environ.get("SOURCE_REPO", "")
match = re.fullmatch(r"ContextualWisdomLab/([A-Za-z0-9_.-]+)", source_repo)
if match is None:
raise SystemExit(f"Invalid organization source repository: {source_repo!r}")
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
print(f"repository={match.group(1)}", file=output)
PY

- name: Mint source-scoped Noema GitHub App token for Code Scanning
if: ${{ always() && !cancelled() && steps.gate.outputs.enabled == 'true' && steps.code_scanning_source.outcome == 'success' }}
id: noema_code_scanning_token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.NOEMA_GITHUB_APP_CLIENT_ID }}
private-key: ${{ secrets.NOEMA_GITHUB_APP_PRIVATE_KEY }}
owner: ContextualWisdomLab
repositories: ${{ steps.code_scanning_source.outputs.repository }}
permission-security-events: read
permission-metadata: read

- name: Emit Strix and GitHub Code Scanning findings to AppGuardrail
if: ${{ always() && !cancelled() && steps.gate.outputs.enabled == 'true' }}
env:
STRIX_ISSUE_APP_TOKEN: ${{ steps.noema_issue_token.outputs.token || '' }}
CODE_SCANNING_SOURCE_TOKEN: ${{ steps.noema_code_scanning_token.outputs.token || '' }}
STRIX_SOURCE_REPO: ${{ github.event.pull_request.base.repo.full_name || github.event.client_payload.target_repository || github.repository }}
STRIX_PR_NUMBER: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.number || github.event.client_payload.pr_number || '' }}
STRIX_HEAD_SHA: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || github.event.client_payload.pr_head_sha || github.sha }}
STRIX_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
STRIX_SCAN_SCOPE: ${{ (github.event_name == 'pull_request_target' || github.event.client_payload.pr_number != '') && 'pr' || 'full' }}
STRIX_SCAN_COMPLETE: ${{ steps.run_strix.outputs.scan_complete || 'false' }}
run: |
set -euo pipefail
emitter_args=(
--run-dir "$GITHUB_WORKSPACE/strix_runs"
--source-repo "$STRIX_SOURCE_REPO"
--issues-repo ContextualWisdomLab/appguardrail
--pr-number "$STRIX_PR_NUMBER"
--head-sha "$STRIX_HEAD_SHA"
--run-url "$STRIX_RUN_URL"
--scope "$STRIX_SCAN_SCOPE"
--include-code-scanning
)
if [ "$STRIX_SCAN_COMPLETE" = "true" ]; then
emitter_args+=(--scan-complete)
fi
python3 "$TRUSTED_STRIX_ISSUE_EMITTER" "${emitter_args[@]}"

- name: Publish same-head manual Strix status
if: ${{ always() && !cancelled() && github.event_name == 'repository_dispatch' && github.event.client_payload.pr_head_sha != '' }}
env:
Expand Down
5 changes: 3 additions & 2 deletions ci-review-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ tenant crossover, stale or concurrent state, dependency/runtime mismatch,
error/rollback behavior, numerical extremes, or mobile/accessibility behavior
as applicable. A green check or absence of a known bug is not a probe. Record
the exact changed path, positive line, counterexample, executed or source-backed
evidence, exactly one `source-line-sha256=<64 lowercase hex>` digest of the cited
current-head line bytes without its line ending, and whether the hypothesis was falsified or confirmed in the
evidence, exactly one `source-line-sha256=<64 lowercase hex>` receipt copied for
the same `path:line` from Trusted changed-line source receipts without calculating,
inferring, or inventing it, and whether the hypothesis was falsified or confirmed in the
`adversarial_validation` control field. APPROVE needs two falsified probes for
material code/workflow/config/package/test changes and one for non-code changes;
REQUEST_CHANGES needs a confirmed probe anchored to a published finding.
Expand Down
3 changes: 2 additions & 1 deletion code-reviewer-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ concurrent state, dependency/runtime mismatch, error and rollback behavior,
numerical extremes, or mobile and accessibility behavior as applicable. Trace
or execute each probe and record the exact changed path, positive line,
hypothesis, attack/counterexample, evidence with exactly one verified
`source-line-sha256=<64 lowercase hex>` digest of that cited current-head line,
`source-line-sha256=<64 lowercase hex>` receipt copied for the same `path:line`
from Trusted changed-line source receipts without calculating, inferring, or inventing it,
and falsified/confirmed outcome in
the workflow's structured `adversarial_validation` control field. Green checks
alone and absence of a known failure are not adversarial evidence.
Expand Down
Loading
Loading