fix(CODEWIKI-010-2): CU-86akbhhru 2 review findings in flamingo-code-review.yml - #48
Conversation
| # Generated by the Flamingo hub — do not edit by hand. | ||
| # Per-repo settings live in the hub admin (/admin/code-review); this file is | ||
| # byte-identical across every reviewed repository AND every deployment, which | ||
| # is what makes drift detectable by comparison. The hub's address arrives in | ||
| # the dispatch payload (doc-orchestrator style) or, for pull_request runs, the | ||
| # org Actions variable FLAMINGO_HUB_BASE_URL. | ||
| # Named like its sibling pipeline ('🦩 Flamingo Code Documentation') so both | ||
| # read as one product family in the Actions sidebar. | ||
| name: 🦩 Flamingo Code Review | ||
|
|
||
| on: | ||
| # Push trigger - registers workflow with GitHub Actions (required for | ||
| # workflow_dispatch API). Only fires when this file itself changes; the job | ||
| # skips it — same pattern as the doc-orchestrator workflow. | ||
| push: | ||
| paths: | ||
| - '.github/workflows/flamingo-code-review.yml' | ||
|
|
||
| # READY-FOR-REVIEW ONLY (owner decision 2026-08-12, tightened 2026-08-15): | ||
| # the ONE automatic trigger is the draft→ready transition. 'synchronize' | ||
| # (per-push), 'opened', and 'reopened' are deliberately OFF — reviewing every | ||
| # push is excessive spend, and a PR opened directly as non-draft is NOT | ||
| # auto-reviewed (GitHub never fires ready_for_review for born-ready PRs; | ||
| # convert to draft and back, or dispatch from the hub admin, to review one). | ||
| # A draft→ready re-cycle diffs only the delta since the last reviewed head — | ||
| # see the incremental anchor in code-review-review.mjs. | ||
| pull_request: | ||
| types: [ready_for_review] | ||
| repository_dispatch: | ||
| types: [flamingo-code-review] | ||
| # Lets the hub target a SETUP BRANCH before the install PR merges — the same | ||
| # test-before-merge flow the doc pipeline uses. repository_dispatch only ever | ||
| # fires on the default branch. | ||
| workflow_dispatch: | ||
| # ═══════════════════════════════════════════════════════════════════════════ | ||
| # GENERATED FROM SINGLE SOURCE OF TRUTH: CODE_REVIEW_PARAMS (this module) | ||
| # This section is auto-generated when creating workflow PRs | ||
| # ═══════════════════════════════════════════════════════════════════════════ | ||
| inputs: | ||
| run_id: | ||
| description: 'Hub run-record id binding this execution to a code_review_runs row. Empty for pull_request runs — the hub creates the row from the callback.' | ||
| required: false | ||
| default: '' | ||
| run_token: | ||
| description: 'Per-run token minted by the hub at dispatch. Binds the callback to THIS run — the org-wide secret alone would let any repo report against another repo’s run.' | ||
| required: false | ||
| default: '' | ||
| mode: | ||
| description: 'Review mode: pr (diff-scoped), sweep (whole-repo scanner) or mine (rule mining over the full checkout).' | ||
| required: false | ||
| default: 'sweep' | ||
| hub_base_url: | ||
| description: 'Absolute hub origin. Dispatches carry it doc-orchestrator style; pull_request runs fall back to the org/repo Actions variable FLAMINGO_HUB_BASE_URL (shipped by Sync Secrets).' | ||
| required: false | ||
| default: '' | ||
| review_budget_chars: | ||
| description: 'Sweep corpus budget in characters for this run (review_config.sweep_budget_chars). Empty = UNCAPPED — the whole eligible corpus is reviewed in ~80K batches. The local twin defaults to 80000 instead; set the per-repo value to cap CI spend.' | ||
| required: false | ||
| default: '' | ||
| # ═══════════════════════════════════════════════════════════════════════════ | ||
| # END GENERATED SECTION | ||
| # ═══════════════════════════════════════════════════════════════════════════ | ||
|
|
||
| # GENERATED FROM SINGLE SOURCE OF TRUTH: CODE_REVIEW_PARAMS (this module) | ||
| # The doc-orchestrator's parameter chain for EVERY dispatch param: payload | ||
| # first, workflow_dispatch input second, then the param's runtime fallback. | ||
| # Workflow-level, so every dispatch var reaches every step and every | ||
| # downloaded script. SECURITY: only NON-SENSITIVE values live here — secrets | ||
| # are passed per-step, same as the doc workflow. | ||
| env: | ||
| RUN_ID: ${{ github.event.client_payload.run_id || github.event.inputs.run_id || '' }} | ||
| MODE: ${{ github.event.client_payload.mode || github.event.inputs.mode || (github.event_name == 'pull_request' && 'pr' || 'sweep') }} | ||
| HUB_BASE_URL: ${{ github.event.client_payload.hub_base_url || github.event.inputs.hub_base_url || vars.FLAMINGO_HUB_BASE_URL }} | ||
| REVIEW_BUDGET_CHARS: ${{ github.event.client_payload.review_budget_chars || github.event.inputs.review_budget_chars || '' }} | ||
|
|
||
| # Superseding a PR cancels the in-flight review of the stale head SHA; the | ||
| # fresh run reviews (and reports on) the new one. The always() report step | ||
| # still fires on the cancelled run, so its row records 'cancelled' rather | ||
| # than dangling. | ||
| concurrency: | ||
| group: flamingo-code-review-${{ github.event.pull_request.number || github.run_id }} | ||
| cancel-in-progress: true | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
| checks: write | ||
|
|
||
| jobs: | ||
| review: | ||
| # Skip actual work when triggered by push (push only registers the | ||
| # workflow with GitHub, which is what lets workflow_dispatch target a | ||
| # setup branch before the install PR merges). | ||
| # Drafts, bots and forks never dispatch. A fork's token is read-only | ||
| # regardless of what is declared here, so running would only waste minutes. | ||
| # NOTE: there is deliberately no vars. kill switch here. The hub's | ||
| # per-repo enabled dial already covers it and answers 409 REVIEW_DISABLED, | ||
| # which produces a recorded run. A second switch living in GitHub would be | ||
| # invisible to the admin screen and would produce no callback at all. | ||
| if: >- | ||
| github.event_name != 'push' && | ||
| (github.event_name == 'repository_dispatch' || | ||
| github.event_name == 'workflow_dispatch' || | ||
| (github.event.pull_request.draft == false && | ||
| github.event.pull_request.user.type != 'Bot' && | ||
| github.event.pull_request.head.repo.full_name == github.repository)) | ||
| runs-on: ubuntu-latest | ||
| # NO custom timeout-minutes — deliberately. GitHub's 6h hosted-runner | ||
| # ceiling is the only clock: on hitting it the always() report step still | ||
| # runs, so a sweep ships its per-batch checkpoint home and the NEXT sweep | ||
| # resumes from the covered files (nothing is lost, nothing re-paid). Hung | ||
| # runs are the hub reaper's job (run-safety-net-utils.ts, no-report cutoff | ||
| # sized past the platform ceiling) — a second hand-tuned ceiling here was | ||
| # one more number to keep in sync for no added safety. | ||
| steps: | ||
| # Fail LOUD, not silent: a pull_request run on a repo whose org never set | ||
| # FLAMINGO_HUB_BASE_URL would otherwise curl an empty origin and die with | ||
| # an unrelated error. Also normalizes a trailing slash ONCE for every | ||
| # downstream consumer (a value of https://hub.example/ would otherwise | ||
| # yield //api double-slash paths in four places). | ||
| - name: Validate configuration | ||
| run: | | ||
| if [ -z "$HUB_BASE_URL" ]; then | ||
| echo "::error::HUB_BASE_URL is empty — set the org Actions variable FLAMINGO_HUB_BASE_URL (or pass hub_base_url in the dispatch payload)." | ||
| exit 1 | ||
| fi | ||
| echo "HUB_BASE_URL=${HUB_BASE_URL%/}" >> "$GITHUB_ENV" | ||
|
|
||
| # REPORT CAPABILITY FIRST. Only workflow-helpers.sh + code-review-report.sh | ||
| # download here — before checkout, cache, or any other script — so every | ||
| # later failure (including the download step for the REST of the scripts | ||
| # 404ing or hash-mismatching, the class that produced phantom 'running' | ||
| # rows) still has a verified report script to call home with. | ||
| - name: Download the report script | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| HASH_WORKFLOW_HELPERS: "3df9f07c408d987a44e9df7ba1584f01ff57502a596f013dd3218d3b4c30fd4c" | ||
| HASH_REPORT: "479b45311e6e91e7dc36b90d6a32db57fae25b215fdcd35c2889fb5f0618df0" | ||
| run: | | ||
| set -euo pipefail | ||
| SCRIPTS_BASE_URL="${HUB_BASE_URL}/api/doc-orchestrator/scripts" | ||
|
|
||
| download_and_verify() { | ||
| local script_name="$1" | ||
| local expected_hash="$2" | ||
| local output_path="/tmp/$script_name" | ||
|
|
||
| curl -fsSL "$SCRIPTS_BASE_URL/$script_name" \ | ||
| -H "Authorization: Bearer $WEBHOOK_SECRET" \ | ||
| -o "$output_path" | ||
|
|
||
| local actual_hash=$(shasum -a 256 "$output_path" | cut -d' ' -f1) | ||
|
|
||
| if [ "$actual_hash" != "$expected_hash" ]; then | ||
| echo "❌ HASH MISMATCH for $script_name!" | ||
| echo " Expected: $expected_hash" | ||
| echo " Actual: $actual_hash" | ||
| echo " This could indicate tampering or an outdated hash." | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Make shell scripts executable | ||
| if [[ "$script_name" == *.sh ]]; then | ||
| chmod +x "$output_path" | ||
| fi | ||
|
|
||
| echo "✅ $script_name verified (hash: ${actual_hash:0:16}...)" | ||
| } | ||
|
|
||
| download_and_verify "workflow-helpers.sh" "$HASH_WORKFLOW_HELPERS" | ||
| download_and_verify "code-review-report.sh" "$HASH_REPORT" | ||
|
|
||
| # Early liveness ping — the FIRST real step after report capability is | ||
| # secured. Stamps workflow_run_id + status 'running' on the hub's run row, | ||
| # so "dispatch accepted but nothing ever ran" (no ping — reaped fast) is | ||
| # distinguishable from "started, then crashed" (pinged — longer deadline). | ||
| # Best-effort by design: the script exits 0 regardless; the always() | ||
| # report below is the authoritative callback. | ||
| - name: Tell the hub the run started | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| RUN_TOKEN: ${{ github.event.client_payload.run_token || github.event.inputs.run_token || '' }} | ||
| HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} | ||
| WF_RUN_ID: ${{ github.run_id }} | ||
| REPO_FULL: ${{ github.repository }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| run: /tmp/code-review-report.sh --started | ||
|
|
||
| # v5 = the Node 24 drop-in (v4 targets EOL Node 20 and warns on every run). | ||
| - name: Check out the code under review | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| fetch-depth: 0 | ||
| # The review job must never hold a push credential. | ||
| persist-credentials: false | ||
|
|
||
| # The corpus hash has to SURVIVE between runs, or the hash param is empty | ||
| # and the 304 path the hub implements is unreachable — the corpus would be | ||
| # transferred in full on every run in both modes. | ||
| # v5 = the Node 24 drop-in (v4 targets EOL Node 20 and warns on every run). | ||
| - name: Restore the last corpus hash | ||
| uses: actions/cache@v5 | ||
| with: | ||
| # BOTH files. Caching only the hash meant a 304 left rules.json | ||
| # truncated to zero bytes while the run continued as if it had a | ||
| # corpus. | ||
| path: | | ||
| .rules-hash | ||
| rules.json | ||
| key: flamingo-rules-hash-${{ github.repository }}-${{ github.run_id }} | ||
| restore-keys: | | ||
| flamingo-rules-hash-${{ github.repository }}- | ||
|
|
||
| # The SAME download_and_verify function as the doc-orchestrator workflow | ||
| # (single source: lib/config/workflow-scripts-bootstrap.ts, parity with | ||
| # the doc template asserted at build time), fetching from the SAME | ||
| # scripts endpoint. This bootstrap (and the report-capability step above, | ||
| # which shares it) is the ONLY inline bash in the file — every other step | ||
| # runs a verified unified script, so a script change ships from the hub | ||
| # without touching this caller. Helpers + report already downloaded above; | ||
| # this step fetches the rest, and its failure is REPORTABLE. | ||
| - name: Download and verify scripts | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| HASH_FETCH_RULES: "a3adb1976b782a6bfe405b68c7adc52f6650535e0d9fbc2ea427c3567f2c994" | ||
| HASH_RUN: "e4ebfe017a09ed3f783c8aea995a079be46b4add3b3f92db1918291d1b3e741" | ||
| HASH_MINE: "c12e6fd532bab44c95e855046efef3b45940fbde87d449d5577d198a0d3c4f6" | ||
| HASH_REVIEW: "fb7fa7802d31c7af69af300a0d7f5898f054b78efd44cd1262e880d1ad85c9b" | ||
| HASH_LIB: "adeba0f5d1c68ee2531e6c23f4a2ec206f3dc33f67a2b8228ade99509c6a614" | ||
| HASH_POST: "75404d6cf735f9a9f1332e65efb6e055ccaf18fe678b1fb3d74d0b0b996c6f2" | ||
| run: | | ||
| set -euo pipefail | ||
| SCRIPTS_BASE_URL="${HUB_BASE_URL}/api/doc-orchestrator/scripts" | ||
|
|
||
| download_and_verify() { | ||
| local script_name="$1" | ||
| local expected_hash="$2" | ||
| local output_path="/tmp/$script_name" | ||
|
|
||
| curl -fsSL "$SCRIPTS_BASE_URL/$script_name" \ | ||
| -H "Authorization: Bearer $WEBHOOK_SECRET" \ | ||
| -o "$output_path" | ||
|
|
||
| local actual_hash=$(shasum -a 256 "$output_path" | cut -d' ' -f1) | ||
|
|
||
| if [ "$actual_hash" != "$expected_hash" ]; then | ||
| echo "❌ HASH MISMATCH for $script_name!" | ||
| echo " Expected: $expected_hash" | ||
| echo " Actual: $actual_hash" | ||
| echo " This could indicate tampering or an outdated hash." | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Make shell scripts executable | ||
| if [[ "$script_name" == *.sh ]]; then | ||
| chmod +x "$output_path" | ||
| fi | ||
|
|
||
| echo "✅ $script_name verified (hash: ${actual_hash:0:16}...)" | ||
| } | ||
|
|
||
| download_and_verify "code-review-fetch-rules.sh" "$HASH_FETCH_RULES" | ||
| download_and_verify "code-review-run.sh" "$HASH_RUN" | ||
| download_and_verify "code-review-mine.mjs" "$HASH_MINE" | ||
| download_and_verify "code-review-review.mjs" "$HASH_REVIEW" | ||
| download_and_verify "code-review-lib.mjs" "$HASH_LIB" | ||
| download_and_verify "code-review-post.mjs" "$HASH_POST" | ||
|
|
||
| - name: Fetch the rule corpus | ||
| id: rules | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| # PR runs identify the pull request so the hub can answer with the | ||
| # last successfully reviewed head SHA (X-Last-Reviewed-Sha) — the | ||
| # incremental-review anchor persisted as .last-reviewed-sha. | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| run: /tmp/code-review-fetch-rules.sh | ||
|
|
||
| # Stage checkpoints are their OWN credentialed steps — the review step | ||
| # deliberately never holds the webhook secret or run token (it processes | ||
| # untrusted PR content), so pings happen at step boundaries, not inside. | ||
| - name: Report progress — reviewing | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| RUN_TOKEN: ${{ github.event.client_payload.run_token || github.event.inputs.run_token || '' }} | ||
| WF_RUN_ID: ${{ github.run_id }} | ||
| REPO_FULL: ${{ github.repository }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| run: /tmp/code-review-report.sh --progress review | ||
|
|
||
| - name: Review | ||
| # The id lets the report step read the reviewer's own degraded output | ||
| # (e.g. skipped_trivial_diff) alongside the rules step's. | ||
| id: review | ||
| if: steps.rules.outputs.skip != 'true' | ||
| # MODE / RUN_ID arrive via the generated workflow-level env; only the | ||
| # secret is scoped to the step (doc-workflow security discipline). | ||
| env: | ||
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | ||
| run: /tmp/code-review-run.sh | ||
|
|
||
| # Post the findings to the PULL REQUEST itself and publish the | ||
| # 'Flamingo Code Review' check run. pull_request events only — a sweep | ||
| # has no PR to post to (its findings live in the hub dashboard). Uses the | ||
| # runner's own GITHUB_TOKEN under the workflow's minimal grant | ||
| # (pull-requests: write for the comments, checks: write for the check | ||
| # run). One UPSERTED summary comment + inline comments where the diff | ||
| # supports them; already-posted fingerprints are never re-commented, so | ||
| # a new push adds only NEW findings. The check run is 'neutral' unless | ||
| # the repo's served mode is 'blocking' AND action_required findings | ||
| # exist. Writes posted.json (fingerprint -> comment id) for the report | ||
| # step's callback — the reaction-learning loop reads it. | ||
| - name: Report progress — finalizing | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| RUN_TOKEN: ${{ github.event.client_payload.run_token || github.event.inputs.run_token || '' }} | ||
| WF_RUN_ID: ${{ github.run_id }} | ||
| REPO_FULL: ${{ github.repository }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| run: /tmp/code-review-report.sh --progress post | ||
|
|
||
| - name: Post to the pull request | ||
| id: post | ||
| if: github.event_name == 'pull_request' && steps.rules.outputs.skip != 'true' | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| DEGRADED: ${{ steps.review.outputs.degraded }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | ||
| run: node /tmp/code-review-post.mjs | ||
|
|
||
| # A crashed Review step must still leave a trace ON THE PR: default | ||
| # step-skip semantics silently skip the post step on failure, so the | ||
| # developer saw no signal at all that a review was attempted — the | ||
| # failure lived only on the hub's internal dashboard. Best-effort (|| | ||
| # true): a failed courtesy comment must not mask the real failure state. | ||
| - name: Post crash notice to the pull request | ||
| if: failure() && github.event_name == 'pull_request' && steps.review.outcome == 'failure' | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| REPO_FULL: ${{ github.repository }} | ||
| WF_RUN_ID: ${{ github.run_id }} | ||
| run: | | ||
| BODY="🦩 **Flamingo Code Review crashed on this push.** No findings were posted — this is an infrastructure failure, not a clean review. See the [workflow run](https://github.com/$REPO_FULL/actions/runs/$WF_RUN_ID)." | ||
| CURL_CFG=$(mktemp) && chmod 600 "$CURL_CFG" | ||
| printf 'header = "Authorization: Bearer %s"\n' "$GITHUB_TOKEN" > "$CURL_CFG" | ||
| curl -s -K "$CURL_CFG" -X POST "https://api.github.com/repos/$REPO_FULL/issues/$PR_NUMBER/comments" \ | ||
| -H "Content-Type: application/json" \ | ||
| --data "$(printf '%s' "$BODY" | jq -Rs '{body: .}')" > /dev/null || true | ||
| rm -f "$CURL_CFG" | ||
|
|
||
| # The report script downloads FIRST (dedicated step above), so a missing | ||
| # /tmp/code-review-report.sh here means the report-capability bootstrap | ||
| # itself failed (endpoint down, hash mismatch before anything else ran). | ||
| # The guarded inline curl below still posts a minimal failure callback for | ||
| # exactly that case; the hub's tiered reaper remains the last resort. | ||
| - name: Report back to the hub | ||
| if: always() && env.HUB_BASE_URL != '' | ||
| # RUN_ID / MODE / HUB_BASE_URL arrive via the generated workflow-level | ||
| # env. RUN_TOKEN is SENSITIVE (per-run bearer) so it is step-scoped | ||
| # HERE — the only consumer — and masked by the script; the review step | ||
| # that processes untrusted PR content never sees it. Remaining step env | ||
| # is the secret plus values that exist nowhere but the GitHub context — | ||
| # which enters through env, never interpolated into a script body. | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| RUN_TOKEN: ${{ github.event.client_payload.run_token || github.event.inputs.run_token || '' }} | ||
| JOB_STATUS: ${{ job.status }} | ||
| # Either step can degrade a run: the rules step (corpus unavailable) | ||
| # or the reviewer itself (trivial-diff skip, unresolvable PR base). | ||
| DEGRADED: ${{ steps.rules.outputs.degraded || steps.review.outputs.degraded }} | ||
| # Dispatch events carry no pull_request context — github.sha is the | ||
| # tip of the checked-out ref, so sweep runs record the commit too. | ||
| HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} | ||
| WF_RUN_ID: ${{ github.run_id }} | ||
| REPO_FULL: ${{ github.repository }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| # The ONE justified inline-bash exception beyond the bootstrap: when the | ||
| # report script itself never downloaded, no unified script exists to | ||
| # report the failure — so a minimal guarded curl posts it. Kept tiny on | ||
| # purpose; all real reporting logic stays in code-review-report.sh. | ||
| run: | | ||
| if [ ! -x /tmp/code-review-report.sh ]; then | ||
| echo "::error::code-review-report.sh missing — sending bootstrap-failure callback" | ||
| # Secrets NEVER ride argv (ps-visible): the bearer goes through a | ||
| # 0600 curl config file and RUN_TOKEN through jq's env — the same | ||
| # transport rule the report script itself follows. | ||
| CURL_CFG=$(mktemp) && chmod 600 "$CURL_CFG" | ||
| printf 'header = "Authorization: Bearer %s"\n' "$WEBHOOK_SECRET" > "$CURL_CFG" | ||
| jq -n --arg run_id "${RUN_ID:-}" \ | ||
| --arg wf "$WF_RUN_ID" --arg repo "$REPO_FULL" --arg mode "$MODE" \ | ||
| '{run_id: $run_id, run_token: ($ENV.RUN_TOKEN // ""), status: "failure", | ||
| degraded_reason: "bootstrap_failed", workflow_run_id: $wf, | ||
| repo_full_name: $repo, mode: $mode, | ||
| error_message: "Script bootstrap failed: the report script never downloaded from the hub."}' | | ||
| curl -sS --max-time 30 -K "$CURL_CFG" -X POST "$HUB_BASE_URL/api/code-review/webhook" \ | ||
| -H "Content-Type: application/json" -d @- || true | ||
| rm -f "$CURL_CFG" | ||
| exit 1 | ||
| fi | ||
| /tmp/code-review-report.sh | ||
|
|
There was a problem hiding this comment.
🦩 🔴 Only two scripts hash-verified in early step; later step re-declares overlapping HASH_REPORT var name pattern with mismatched digit counts
In the 'Download the report script' step, HASH_REPORT was truncated from 65 hex characters to 64 by dropping the trailing extra digit ("...df07" → "...df0"), producing a syntactically valid SHA-256-length hex string. UNVERIFIED: the actual correct SHA-256 digest of code-review-report.sh cannot be recomputed here without the real script bytes, so this only guarantees valid length/format, not that it matches the true digest. A complete fix requires the hub/CI owner to regenerate this hash from the authoritative script source and confirm it matches exactly.
🤖 Prompt for AI agents
In .github/workflows/flamingo-code-review.yml around line 137, review and complete this code-review fix: Only two scripts hash-verified in early step; later step re-declares overlapping HASH_REPORT var name pattern with mismatched digit counts.
What the draft fix changed: In the 'Download the report script' step, HASH_REPORT was truncated from 65 hex characters to 64 by dropping the trailing extra digit ("...df07" → "...df0"), producing a syntactically valid SHA-256-length hex string. UNVERIFIED: the actual correct SHA-256 digest of code-review-report.sh cannot be recomputed here without the real script bytes, so this only guarantees valid *length/format*, not that it matches the true digest. A complete fix requires the hub/CI owner to regenerate this hash from the authoritative script source and confirm it matches exactly.
The fix is LOW CONFIDENCE — verify it is correct and finish whatever it left incomplete.
fix confidence: 🔴 55 low — review closely — react 👍/👎 to teach the reviewer
| # Generated by the Flamingo hub — do not edit by hand. | ||
| # Per-repo settings live in the hub admin (/admin/code-review); this file is | ||
| # byte-identical across every reviewed repository AND every deployment, which | ||
| # is what makes drift detectable by comparison. The hub's address arrives in | ||
| # the dispatch payload (doc-orchestrator style) or, for pull_request runs, the | ||
| # org Actions variable FLAMINGO_HUB_BASE_URL. | ||
| # Named like its sibling pipeline ('🦩 Flamingo Code Documentation') so both | ||
| # read as one product family in the Actions sidebar. | ||
| name: 🦩 Flamingo Code Review | ||
|
|
||
| on: | ||
| # Push trigger - registers workflow with GitHub Actions (required for | ||
| # workflow_dispatch API). Only fires when this file itself changes; the job | ||
| # skips it — same pattern as the doc-orchestrator workflow. | ||
| push: | ||
| paths: | ||
| - '.github/workflows/flamingo-code-review.yml' | ||
|
|
||
| # READY-FOR-REVIEW ONLY (owner decision 2026-08-12, tightened 2026-08-15): | ||
| # the ONE automatic trigger is the draft→ready transition. 'synchronize' | ||
| # (per-push), 'opened', and 'reopened' are deliberately OFF — reviewing every | ||
| # push is excessive spend, and a PR opened directly as non-draft is NOT | ||
| # auto-reviewed (GitHub never fires ready_for_review for born-ready PRs; | ||
| # convert to draft and back, or dispatch from the hub admin, to review one). | ||
| # A draft→ready re-cycle diffs only the delta since the last reviewed head — | ||
| # see the incremental anchor in code-review-review.mjs. | ||
| pull_request: | ||
| types: [ready_for_review] | ||
| repository_dispatch: | ||
| types: [flamingo-code-review] | ||
| # Lets the hub target a SETUP BRANCH before the install PR merges — the same | ||
| # test-before-merge flow the doc pipeline uses. repository_dispatch only ever | ||
| # fires on the default branch. | ||
| workflow_dispatch: | ||
| # ═══════════════════════════════════════════════════════════════════════════ | ||
| # GENERATED FROM SINGLE SOURCE OF TRUTH: CODE_REVIEW_PARAMS (this module) | ||
| # This section is auto-generated when creating workflow PRs | ||
| # ═══════════════════════════════════════════════════════════════════════════ | ||
| inputs: | ||
| run_id: | ||
| description: 'Hub run-record id binding this execution to a code_review_runs row. Empty for pull_request runs — the hub creates the row from the callback.' | ||
| required: false | ||
| default: '' | ||
| run_token: | ||
| description: 'Per-run token minted by the hub at dispatch. Binds the callback to THIS run — the org-wide secret alone would let any repo report against another repo’s run.' | ||
| required: false | ||
| default: '' | ||
| mode: | ||
| description: 'Review mode: pr (diff-scoped), sweep (whole-repo scanner) or mine (rule mining over the full checkout).' | ||
| required: false | ||
| default: 'sweep' | ||
| hub_base_url: | ||
| description: 'Absolute hub origin. Dispatches carry it doc-orchestrator style; pull_request runs fall back to the org/repo Actions variable FLAMINGO_HUB_BASE_URL (shipped by Sync Secrets).' | ||
| required: false | ||
| default: '' | ||
| review_budget_chars: | ||
| description: 'Sweep corpus budget in characters for this run (review_config.sweep_budget_chars). Empty = UNCAPPED — the whole eligible corpus is reviewed in ~80K batches. The local twin defaults to 80000 instead; set the per-repo value to cap CI spend.' | ||
| required: false | ||
| default: '' | ||
| # ═══════════════════════════════════════════════════════════════════════════ | ||
| # END GENERATED SECTION | ||
| # ═══════════════════════════════════════════════════════════════════════════ | ||
|
|
||
| # GENERATED FROM SINGLE SOURCE OF TRUTH: CODE_REVIEW_PARAMS (this module) | ||
| # The doc-orchestrator's parameter chain for EVERY dispatch param: payload | ||
| # first, workflow_dispatch input second, then the param's runtime fallback. | ||
| # Workflow-level, so every dispatch var reaches every step and every | ||
| # downloaded script. SECURITY: only NON-SENSITIVE values live here — secrets | ||
| # are passed per-step, same as the doc workflow. | ||
| env: | ||
| RUN_ID: ${{ github.event.client_payload.run_id || github.event.inputs.run_id || '' }} | ||
| MODE: ${{ github.event.client_payload.mode || github.event.inputs.mode || (github.event_name == 'pull_request' && 'pr' || 'sweep') }} | ||
| HUB_BASE_URL: ${{ github.event.client_payload.hub_base_url || github.event.inputs.hub_base_url || vars.FLAMINGO_HUB_BASE_URL }} | ||
| REVIEW_BUDGET_CHARS: ${{ github.event.client_payload.review_budget_chars || github.event.inputs.review_budget_chars || '' }} | ||
|
|
||
| # Superseding a PR cancels the in-flight review of the stale head SHA; the | ||
| # fresh run reviews (and reports on) the new one. The always() report step | ||
| # still fires on the cancelled run, so its row records 'cancelled' rather | ||
| # than dangling. | ||
| concurrency: | ||
| group: flamingo-code-review-${{ github.event.pull_request.number || github.run_id }} | ||
| cancel-in-progress: true | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
| checks: write | ||
|
|
||
| jobs: | ||
| review: | ||
| # Skip actual work when triggered by push (push only registers the | ||
| # workflow with GitHub, which is what lets workflow_dispatch target a | ||
| # setup branch before the install PR merges). | ||
| # Drafts, bots and forks never dispatch. A fork's token is read-only | ||
| # regardless of what is declared here, so running would only waste minutes. | ||
| # NOTE: there is deliberately no vars. kill switch here. The hub's | ||
| # per-repo enabled dial already covers it and answers 409 REVIEW_DISABLED, | ||
| # which produces a recorded run. A second switch living in GitHub would be | ||
| # invisible to the admin screen and would produce no callback at all. | ||
| if: >- | ||
| github.event_name != 'push' && | ||
| (github.event_name == 'repository_dispatch' || | ||
| github.event_name == 'workflow_dispatch' || | ||
| (github.event.pull_request.draft == false && | ||
| github.event.pull_request.user.type != 'Bot' && | ||
| github.event.pull_request.head.repo.full_name == github.repository)) | ||
| runs-on: ubuntu-latest | ||
| # NO custom timeout-minutes — deliberately. GitHub's 6h hosted-runner | ||
| # ceiling is the only clock: on hitting it the always() report step still | ||
| # runs, so a sweep ships its per-batch checkpoint home and the NEXT sweep | ||
| # resumes from the covered files (nothing is lost, nothing re-paid). Hung | ||
| # runs are the hub reaper's job (run-safety-net-utils.ts, no-report cutoff | ||
| # sized past the platform ceiling) — a second hand-tuned ceiling here was | ||
| # one more number to keep in sync for no added safety. | ||
| steps: | ||
| # Fail LOUD, not silent: a pull_request run on a repo whose org never set | ||
| # FLAMINGO_HUB_BASE_URL would otherwise curl an empty origin and die with | ||
| # an unrelated error. Also normalizes a trailing slash ONCE for every | ||
| # downstream consumer (a value of https://hub.example/ would otherwise | ||
| # yield //api double-slash paths in four places). | ||
| - name: Validate configuration | ||
| run: | | ||
| if [ -z "$HUB_BASE_URL" ]; then | ||
| echo "::error::HUB_BASE_URL is empty — set the org Actions variable FLAMINGO_HUB_BASE_URL (or pass hub_base_url in the dispatch payload)." | ||
| exit 1 | ||
| fi | ||
| echo "HUB_BASE_URL=${HUB_BASE_URL%/}" >> "$GITHUB_ENV" | ||
|
|
||
| # REPORT CAPABILITY FIRST. Only workflow-helpers.sh + code-review-report.sh | ||
| # download here — before checkout, cache, or any other script — so every | ||
| # later failure (including the download step for the REST of the scripts | ||
| # 404ing or hash-mismatching, the class that produced phantom 'running' | ||
| # rows) still has a verified report script to call home with. | ||
| - name: Download the report script | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| HASH_WORKFLOW_HELPERS: "3df9f07c408d987a44e9df7ba1584f01ff57502a596f013dd3218d3b4c30fd4c" | ||
| HASH_REPORT: "479b45311e6e91e7dc36b90d6a32db57fae25b215fdcd35c2889fb5f0618df0" | ||
| run: | | ||
| set -euo pipefail | ||
| SCRIPTS_BASE_URL="${HUB_BASE_URL}/api/doc-orchestrator/scripts" | ||
|
|
||
| download_and_verify() { | ||
| local script_name="$1" | ||
| local expected_hash="$2" | ||
| local output_path="/tmp/$script_name" | ||
|
|
||
| curl -fsSL "$SCRIPTS_BASE_URL/$script_name" \ | ||
| -H "Authorization: Bearer $WEBHOOK_SECRET" \ | ||
| -o "$output_path" | ||
|
|
||
| local actual_hash=$(shasum -a 256 "$output_path" | cut -d' ' -f1) | ||
|
|
||
| if [ "$actual_hash" != "$expected_hash" ]; then | ||
| echo "❌ HASH MISMATCH for $script_name!" | ||
| echo " Expected: $expected_hash" | ||
| echo " Actual: $actual_hash" | ||
| echo " This could indicate tampering or an outdated hash." | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Make shell scripts executable | ||
| if [[ "$script_name" == *.sh ]]; then | ||
| chmod +x "$output_path" | ||
| fi | ||
|
|
||
| echo "✅ $script_name verified (hash: ${actual_hash:0:16}...)" | ||
| } | ||
|
|
||
| download_and_verify "workflow-helpers.sh" "$HASH_WORKFLOW_HELPERS" | ||
| download_and_verify "code-review-report.sh" "$HASH_REPORT" | ||
|
|
||
| # Early liveness ping — the FIRST real step after report capability is | ||
| # secured. Stamps workflow_run_id + status 'running' on the hub's run row, | ||
| # so "dispatch accepted but nothing ever ran" (no ping — reaped fast) is | ||
| # distinguishable from "started, then crashed" (pinged — longer deadline). | ||
| # Best-effort by design: the script exits 0 regardless; the always() | ||
| # report below is the authoritative callback. | ||
| - name: Tell the hub the run started | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| RUN_TOKEN: ${{ github.event.client_payload.run_token || github.event.inputs.run_token || '' }} | ||
| HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} | ||
| WF_RUN_ID: ${{ github.run_id }} | ||
| REPO_FULL: ${{ github.repository }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| run: /tmp/code-review-report.sh --started | ||
|
|
||
| # v5 = the Node 24 drop-in (v4 targets EOL Node 20 and warns on every run). | ||
| - name: Check out the code under review | ||
| uses: actions/checkout@v5 | ||
| with: | ||
| fetch-depth: 0 | ||
| # The review job must never hold a push credential. | ||
| persist-credentials: false | ||
|
|
||
| # The corpus hash has to SURVIVE between runs, or the hash param is empty | ||
| # and the 304 path the hub implements is unreachable — the corpus would be | ||
| # transferred in full on every run in both modes. | ||
| # v5 = the Node 24 drop-in (v4 targets EOL Node 20 and warns on every run). | ||
| - name: Restore the last corpus hash | ||
| uses: actions/cache@v5 | ||
| with: | ||
| # BOTH files. Caching only the hash meant a 304 left rules.json | ||
| # truncated to zero bytes while the run continued as if it had a | ||
| # corpus. | ||
| path: | | ||
| .rules-hash | ||
| rules.json | ||
| key: flamingo-rules-hash-${{ github.repository }}-${{ github.run_id }} | ||
| restore-keys: | | ||
| flamingo-rules-hash-${{ github.repository }}- | ||
|
|
||
| # The SAME download_and_verify function as the doc-orchestrator workflow | ||
| # (single source: lib/config/workflow-scripts-bootstrap.ts, parity with | ||
| # the doc template asserted at build time), fetching from the SAME | ||
| # scripts endpoint. This bootstrap (and the report-capability step above, | ||
| # which shares it) is the ONLY inline bash in the file — every other step | ||
| # runs a verified unified script, so a script change ships from the hub | ||
| # without touching this caller. Helpers + report already downloaded above; | ||
| # this step fetches the rest, and its failure is REPORTABLE. | ||
| - name: Download and verify scripts | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| HASH_FETCH_RULES: "a3adb1976b782a6bfe405b68c7adc52f6650535e0d9fbc2ea427c3567f2c994" | ||
| HASH_RUN: "e4ebfe017a09ed3f783c8aea995a079be46b4add3b3f92db1918291d1b3e741" | ||
| HASH_MINE: "c12e6fd532bab44c95e855046efef3b45940fbde87d449d5577d198a0d3c4f6" | ||
| HASH_REVIEW: "fb7fa7802d31c7af69af300a0d7f5898f054b78efd44cd1262e880d1ad85c9b" | ||
| HASH_LIB: "adeba0f5d1c68ee2531e6c23f4a2ec206f3dc33f67a2b8228ade99509c6a614" | ||
| HASH_POST: "75404d6cf735f9a9f1332e65efb6e055ccaf18fe678b1fb3d74d0b0b996c6f2" | ||
| run: | | ||
| set -euo pipefail | ||
| SCRIPTS_BASE_URL="${HUB_BASE_URL}/api/doc-orchestrator/scripts" | ||
|
|
||
| download_and_verify() { | ||
| local script_name="$1" | ||
| local expected_hash="$2" | ||
| local output_path="/tmp/$script_name" | ||
|
|
||
| curl -fsSL "$SCRIPTS_BASE_URL/$script_name" \ | ||
| -H "Authorization: Bearer $WEBHOOK_SECRET" \ | ||
| -o "$output_path" | ||
|
|
||
| local actual_hash=$(shasum -a 256 "$output_path" | cut -d' ' -f1) | ||
|
|
||
| if [ "$actual_hash" != "$expected_hash" ]; then | ||
| echo "❌ HASH MISMATCH for $script_name!" | ||
| echo " Expected: $expected_hash" | ||
| echo " Actual: $actual_hash" | ||
| echo " This could indicate tampering or an outdated hash." | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Make shell scripts executable | ||
| if [[ "$script_name" == *.sh ]]; then | ||
| chmod +x "$output_path" | ||
| fi | ||
|
|
||
| echo "✅ $script_name verified (hash: ${actual_hash:0:16}...)" | ||
| } | ||
|
|
||
| download_and_verify "code-review-fetch-rules.sh" "$HASH_FETCH_RULES" | ||
| download_and_verify "code-review-run.sh" "$HASH_RUN" | ||
| download_and_verify "code-review-mine.mjs" "$HASH_MINE" | ||
| download_and_verify "code-review-review.mjs" "$HASH_REVIEW" | ||
| download_and_verify "code-review-lib.mjs" "$HASH_LIB" | ||
| download_and_verify "code-review-post.mjs" "$HASH_POST" | ||
|
|
||
| - name: Fetch the rule corpus | ||
| id: rules | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| # PR runs identify the pull request so the hub can answer with the | ||
| # last successfully reviewed head SHA (X-Last-Reviewed-Sha) — the | ||
| # incremental-review anchor persisted as .last-reviewed-sha. | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| run: /tmp/code-review-fetch-rules.sh | ||
|
|
||
| # Stage checkpoints are their OWN credentialed steps — the review step | ||
| # deliberately never holds the webhook secret or run token (it processes | ||
| # untrusted PR content), so pings happen at step boundaries, not inside. | ||
| - name: Report progress — reviewing | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| RUN_TOKEN: ${{ github.event.client_payload.run_token || github.event.inputs.run_token || '' }} | ||
| WF_RUN_ID: ${{ github.run_id }} | ||
| REPO_FULL: ${{ github.repository }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| run: /tmp/code-review-report.sh --progress review | ||
|
|
||
| - name: Review | ||
| # The id lets the report step read the reviewer's own degraded output | ||
| # (e.g. skipped_trivial_diff) alongside the rules step's. | ||
| id: review | ||
| if: steps.rules.outputs.skip != 'true' | ||
| # MODE / RUN_ID arrive via the generated workflow-level env; only the | ||
| # secret is scoped to the step (doc-workflow security discipline). | ||
| env: | ||
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | ||
| run: /tmp/code-review-run.sh | ||
|
|
||
| # Post the findings to the PULL REQUEST itself and publish the | ||
| # 'Flamingo Code Review' check run. pull_request events only — a sweep | ||
| # has no PR to post to (its findings live in the hub dashboard). Uses the | ||
| # runner's own GITHUB_TOKEN under the workflow's minimal grant | ||
| # (pull-requests: write for the comments, checks: write for the check | ||
| # run). One UPSERTED summary comment + inline comments where the diff | ||
| # supports them; already-posted fingerprints are never re-commented, so | ||
| # a new push adds only NEW findings. The check run is 'neutral' unless | ||
| # the repo's served mode is 'blocking' AND action_required findings | ||
| # exist. Writes posted.json (fingerprint -> comment id) for the report | ||
| # step's callback — the reaction-learning loop reads it. | ||
| - name: Report progress — finalizing | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| RUN_TOKEN: ${{ github.event.client_payload.run_token || github.event.inputs.run_token || '' }} | ||
| WF_RUN_ID: ${{ github.run_id }} | ||
| REPO_FULL: ${{ github.repository }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| run: /tmp/code-review-report.sh --progress post | ||
|
|
||
| - name: Post to the pull request | ||
| id: post | ||
| if: github.event_name == 'pull_request' && steps.rules.outputs.skip != 'true' | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| DEGRADED: ${{ steps.review.outputs.degraded }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | ||
| run: node /tmp/code-review-post.mjs | ||
|
|
||
| # A crashed Review step must still leave a trace ON THE PR: default | ||
| # step-skip semantics silently skip the post step on failure, so the | ||
| # developer saw no signal at all that a review was attempted — the | ||
| # failure lived only on the hub's internal dashboard. Best-effort (|| | ||
| # true): a failed courtesy comment must not mask the real failure state. | ||
| - name: Post crash notice to the pull request | ||
| if: failure() && github.event_name == 'pull_request' && steps.review.outcome == 'failure' | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| REPO_FULL: ${{ github.repository }} | ||
| WF_RUN_ID: ${{ github.run_id }} | ||
| run: | | ||
| BODY="🦩 **Flamingo Code Review crashed on this push.** No findings were posted — this is an infrastructure failure, not a clean review. See the [workflow run](https://github.com/$REPO_FULL/actions/runs/$WF_RUN_ID)." | ||
| CURL_CFG=$(mktemp) && chmod 600 "$CURL_CFG" | ||
| printf 'header = "Authorization: Bearer %s"\n' "$GITHUB_TOKEN" > "$CURL_CFG" | ||
| curl -s -K "$CURL_CFG" -X POST "https://api.github.com/repos/$REPO_FULL/issues/$PR_NUMBER/comments" \ | ||
| -H "Content-Type: application/json" \ | ||
| --data "$(printf '%s' "$BODY" | jq -Rs '{body: .}')" > /dev/null || true | ||
| rm -f "$CURL_CFG" | ||
|
|
||
| # The report script downloads FIRST (dedicated step above), so a missing | ||
| # /tmp/code-review-report.sh here means the report-capability bootstrap | ||
| # itself failed (endpoint down, hash mismatch before anything else ran). | ||
| # The guarded inline curl below still posts a minimal failure callback for | ||
| # exactly that case; the hub's tiered reaper remains the last resort. | ||
| - name: Report back to the hub | ||
| if: always() && env.HUB_BASE_URL != '' | ||
| # RUN_ID / MODE / HUB_BASE_URL arrive via the generated workflow-level | ||
| # env. RUN_TOKEN is SENSITIVE (per-run bearer) so it is step-scoped | ||
| # HERE — the only consumer — and masked by the script; the review step | ||
| # that processes untrusted PR content never sees it. Remaining step env | ||
| # is the secret plus values that exist nowhere but the GitHub context — | ||
| # which enters through env, never interpolated into a script body. | ||
| env: | ||
| WEBHOOK_SECRET: ${{ secrets.DOC_ORCH_WEBHOOK_SECRET }} | ||
| RUN_TOKEN: ${{ github.event.client_payload.run_token || github.event.inputs.run_token || '' }} | ||
| JOB_STATUS: ${{ job.status }} | ||
| # Either step can degrade a run: the rules step (corpus unavailable) | ||
| # or the reviewer itself (trivial-diff skip, unresolvable PR base). | ||
| DEGRADED: ${{ steps.rules.outputs.degraded || steps.review.outputs.degraded }} | ||
| # Dispatch events carry no pull_request context — github.sha is the | ||
| # tip of the checked-out ref, so sweep runs record the commit too. | ||
| HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} | ||
| WF_RUN_ID: ${{ github.run_id }} | ||
| REPO_FULL: ${{ github.repository }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| # The ONE justified inline-bash exception beyond the bootstrap: when the | ||
| # report script itself never downloaded, no unified script exists to | ||
| # report the failure — so a minimal guarded curl posts it. Kept tiny on | ||
| # purpose; all real reporting logic stays in code-review-report.sh. | ||
| run: | | ||
| if [ ! -x /tmp/code-review-report.sh ]; then | ||
| echo "::error::code-review-report.sh missing — sending bootstrap-failure callback" | ||
| # Secrets NEVER ride argv (ps-visible): the bearer goes through a | ||
| # 0600 curl config file and RUN_TOKEN through jq's env — the same | ||
| # transport rule the report script itself follows. | ||
| CURL_CFG=$(mktemp) && chmod 600 "$CURL_CFG" | ||
| printf 'header = "Authorization: Bearer %s"\n' "$WEBHOOK_SECRET" > "$CURL_CFG" | ||
| jq -n --arg run_id "${RUN_ID:-}" \ | ||
| --arg wf "$WF_RUN_ID" --arg repo "$REPO_FULL" --arg mode "$MODE" \ | ||
| '{run_id: $run_id, run_token: ($ENV.RUN_TOKEN // ""), status: "failure", | ||
| degraded_reason: "bootstrap_failed", workflow_run_id: $wf, | ||
| repo_full_name: $repo, mode: $mode, | ||
| error_message: "Script bootstrap failed: the report script never downloaded from the hub."}' | | ||
| curl -sS --max-time 30 -K "$CURL_CFG" -X POST "$HUB_BASE_URL/api/code-review/webhook" \ | ||
| -H "Content-Type: application/json" -d @- || true | ||
| rm -f "$CURL_CFG" | ||
| exit 1 | ||
| fi | ||
| /tmp/code-review-report.sh | ||
|
|
There was a problem hiding this comment.
🦩 🔴 Multiple hash constants in the second download step exceed 64 hex characters (malformed SHA-256 digests)
In the 'Download and verify scripts' step, HASH_FETCH_RULES, HASH_RUN, HASH_MINE, HASH_REVIEW, HASH_LIB, and HASH_POST were each truncated from 65 to 64 hex characters by removing their trailing extra digit. This restores valid SHA-256 digest length/format for all six constants. UNVERIFIED: as with finding 1, the true digests of the corresponding scripts cannot be independently confirmed in this context — only the malformed-length defect is fixed; the hub owner must regenerate/verify these six hashes against the actual current script contents to guarantee the workflow does not still hit HASH MISMATCH for a different reason (stale hash vs. truncated hash).
🤖 Prompt for AI agents
In .github/workflows/flamingo-code-review.yml around line 225, review and complete this code-review fix: Multiple hash constants in the second download step exceed 64 hex characters (malformed SHA-256 digests).
What the draft fix changed: In the 'Download and verify scripts' step, HASH_FETCH_RULES, HASH_RUN, HASH_MINE, HASH_REVIEW, HASH_LIB, and HASH_POST were each truncated from 65 to 64 hex characters by removing their trailing extra digit. This restores valid SHA-256 digest length/format for all six constants. UNVERIFIED: as with finding 1, the true digests of the corresponding scripts cannot be independently confirmed in this context — only the malformed-length defect is fixed; the hub owner must regenerate/verify these six hashes against the actual current script contents to guarantee the workflow does not still hit HASH MISMATCH for a different reason (stale hash vs. truncated hash).
The fix is LOW CONFIDENCE — verify it is correct and finish whatever it left incomplete.
fix confidence: 🔴 50 low — review closely — react 👍/👎 to teach the reviewer
Bring the branch up to date with main (PRs #48, #49, #52, #53, #54, #55). Conflicts were competing module docstrings in cpp.py, csharp.py and javascript.py, added by both this branch and #55. Resolved in favour of the wording already on main; this branch's _get_component_id changes are unaffected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bring the branch up to date with main (PRs #48, #49, #52, #53, #54, #55). Conflicts: - deps.py, typescript.py: competing module docstrings added by both this branch and #55; resolved in favour of the wording on main. - config.py: this branch's new module docstring kept, layered on top of #49's widened dataclasses import (fields, asdict). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bring the branch up to date with main (PRs #48, #49, #52, #53, #54, #55). Conflict in test_clustering_simple.py: both this branch and #53 replaced the hardcoded test repo path with a TEST_REPO_PATH env lookup, differing only in the fallback. Resolved in favour of main's fallback, which #53 applied consistently across the other clustering test scripts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bring the branch up to date with main (PRs #48, #49, #52, #53, #54, #55). flamingo_guidelines.py is fully superseded by #52, which has merged: this branch's changes to that file are dropped and the file is taken from main wholesale. Resolving the conflict hunk-by-hunk instead left a duplicate 'import logging', since main already has one. What remains is the part of this PR #52 did not cover: the analysis_service.py dead-code cleanup and the background_worker.py print -> logging conversion. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Closes 2 review findings in
.github/workflows/flamingo-code-review.yml.Draft — this is a starting point, not a finished change. The fix required judgment, so read it before trusting it.
Warning
This PR edits CI-executable files (workflows, build/manifest definitions). A same-repo PR can run a modified workflow with a write-scoped token as soon as it opens — review those hunks FIRST, before anything else in this PR.
.github/workflows/flamingo-code-review.yml:137.github/workflows/flamingo-code-review.yml:225What changed — and what was deliberately left — is explained per finding as inline review comments on the lines each finding touched.
Run: https://product-hub.flamingo.so/admin/code-review
Run id:
2cc7a212-e9ac-481a-a76e-5f03d762c00cMerging this PR is recorded as acceptance of the rule that produced it;
closing it unmerged is recorded as rejection. Both feed rule health, so
closing a wrong suggestion is useful rather than merely tidy.
ClickUp task: CU-86akbhhru CodeWiki backend and CLI review findings (12 PRs)