-
-
Notifications
You must be signed in to change notification settings - Fork 323
fix(ci): use grokBuildText and skip maintainer auto-review #1279
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1707687
beb06c2
9aac145
4eca0d4
8734c6f
a20c6af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,12 +3,24 @@ | |
| */ | ||
|
|
||
| import { spawn } from 'node:child_process' | ||
| import { homedir } from 'node:os' | ||
| import { readFile } from 'node:fs/promises' | ||
| import { resolve } from 'node:path' | ||
| import { join, resolve } from 'node:path' | ||
| import process from 'node:process' | ||
| import { fileURLToPath } from 'node:url' | ||
| import { chat } from '@tanstack/ai' | ||
| import { grokText } from '@tanstack/ai-grok' | ||
| import { | ||
| GROK_CLI_INSTALL_COMMAND, | ||
| grokBuildText, | ||
| } from '@tanstack/ai-grok-build' | ||
| import { | ||
| createSecrets, | ||
| defineSandbox, | ||
| defineWorkspace, | ||
| localSource, | ||
| withSandbox, | ||
| } from '@tanstack/ai-sandbox' | ||
| import { localProcessSandbox } from '@tanstack/ai-sandbox-local-process' | ||
| import { | ||
| loadConfig, | ||
| isRosterMaintainer, | ||
|
|
@@ -119,21 +131,44 @@ type ReviewInput = { | |
| /** | ||
| * Production Grok review step for `runReviewJob`. | ||
| * | ||
| * Tools run first (read/edit files). Then `outputSchema` returns the verdict. | ||
| * Do not call this from unit tests. | ||
| * `grokBuildText` streams tools first, then a `structured-output.complete` | ||
| * event. Do not call this from unit tests. | ||
| */ | ||
| export function createGrokReview() { | ||
| return async (input: ReviewInput) => { | ||
| const xaiKey = process.env.XAI_API_KEY | ||
| const sandbox = defineSandbox({ | ||
| id: 'ai-review', | ||
| provider: localProcessSandbox({ | ||
| dir: input.worktreeRoot, | ||
| removeOnDestroy: false, | ||
| }), | ||
| workspace: defineWorkspace({ | ||
| source: localSource(input.worktreeRoot), | ||
| setup: ({ serial }) => serial(GROK_CLI_INSTALL_COMMAND), | ||
| ...(xaiKey !== undefined && xaiKey.length > 0 | ||
| ? { secrets: createSecrets({ XAI_API_KEY: xaiKey }) } | ||
|
Comment on lines
+148
to
+150
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: # Inspect the exact workspace bootstrap path, provider environment handling, and
# the command definition/call site needed to establish whether setup can read
# XAI_API_KEY.
printf '%s\n' '--- bootstrapWorkspace and workspace types ---'
rg -n -A90 -B25 'function bootstrapWorkspace|bootstrapWorkspace|interface Workspace|type Workspace|setup:' packages/ai-sandbox agent-scripts/ai-review/run.ts
printf '%s\n' '--- provider create implementations ---'
rg -n -A100 -B20 'async create|create\(' packages/ai-sandbox-local-process packages/ai-sandbox packages/ai-grok-build | head -420
printf '%s\n' '--- Grok install command and review workflow context ---'
rg -n -A35 -B25 'GROK_CLI_INSTALL_COMMAND|xaiKey|createSecrets|grokBuild|bootstrapWorkspace' agent-scripts/ai-review/run.tsRepository: TanStack/ai Length of output: 50370 🏁 Script executed: # Read only the implementations and declarations that determine whether
# resolved secrets enter the bootstrap shell and where the install command comes
# from.
printf '%s\n' '--- bootstrap implementation candidates ---'
rg -l 'bootstrapWorkspace' packages/ai-sandbox/src packages/ai-sandbox-local-process agent-scripts | xargs -r -n1 echo
printf '%s\n' '--- bootstrap implementation ---'
rg -n -A180 -B20 'export (async )?function bootstrapWorkspace|async function bootstrapWorkspace|const bootstrapWorkspace' packages/ai-sandbox/src
printf '%s\n' '--- workspace contract and setup command declaration ---'
rg -n -A80 -B20 'GROK_CLI_INSTALL_COMMAND' agent-scripts packages
rg -n -A100 -B20 'type WorkspaceDefinition|interface WorkspaceDefinition|setup\?:|secrets\?:' packages/ai-sandbox/srcRepository: TanStack/ai Length of output: 35592 🏁 Script executed: # Establish the remaining trust-boundary facts: how the local provider stores
# environment variables, and whether the review workflow executes PR-controlled
# repository code with XAI_API_KEY present.
printf '%s\n' '--- local-process environment and execution ---'
rg -n -A100 -B20 'class LocalProcess|env:|set\(.*env|process\.exec|async exec|function exec' packages/ai-sandbox-local-process/src packages/ai-sandbox/src
printf '%s\n' '--- review workflow checkout and secret usage ---'
fd -t f -e yml -e yaml .github/workflows | xargs -r rg -n -A35 -B20 'ai-review|XAI_API_KEY|checkout|pull_request_target|pull_request|runReviewJob|tsx|run\.ts'Repository: TanStack/ai Length of output: 50368 🏁 Script executed: # The previous output established secret injection before setup but was too broad
# to show the workflow. Narrow the query to workflow files and the local
# provider's env implementation.
printf '%s\n' '--- local-process source files ---'
fd -t f . packages/ai-sandbox-local-process/src
printf '%s\n' '--- local-process env/process methods ---'
rg -n -A45 -B15 'env\s*=|env:|setEnv|class LocalProcess|process\.exec|exec\(command|spawn\(' packages/ai-sandbox-local-process/src
printf '%s\n' '--- workflow files ---'
fd -t f -e yml -e yaml .github/workflows
printf '%s\n' '--- workflow security and execution lines ---'
fd -t f -e yml -e yaml .github/workflows --exec rg -n -A30 -B15 'XAI_API_KEY|pull_request_target|pull_request:|actions/checkout|runReviewJob|ai-review|tsx|node .*run'Repository: TanStack/ai Length of output: 40180 🏁 Script executed: # Locate workflow files with git's tracked-file index, then inspect only the
# review workflow and its trigger/checkout/secret lines.
git ls-files '.github/workflows/*' | sort
git ls-files '.github/workflows/*' | xargs -r rg -n -A35 -B20 'XAI_API_KEY|pull_request_target|pull_request:|actions/checkout|ai-review|runReviewJob|tsx|node .*run'Repository: TanStack/ai Length of output: 35639 Sensitive Data Exposure (CWE-200): Exposure of Sensitive Information to an Unauthorized Actor Reachability: External · Exploitability: Moderate Do not expose The 🤖 Prompt for AI Agents |
||
| : {}), | ||
| }), | ||
| lifecycle: { reuse: 'none', destroyOnComplete: false }, | ||
| }) | ||
| const result = await chat({ | ||
| adapter: grokText('grok-4.6'), | ||
| modelOptions: { reasoning: { effort: 'high' } }, | ||
| adapter: grokBuildText('grok-4.6', { | ||
| authMode: 'api-key', | ||
| protocol: 'streaming-json', | ||
| cwd: input.worktreeRoot, | ||
| grokExecutable: join(homedir(), '.grok', 'bin', 'grok'), | ||
| }), | ||
| tools: createReviewTools({ worktreeRoot: input.worktreeRoot }), | ||
| outputSchema: reviewVerdictSchema, | ||
| middleware: [withSandbox(sandbox)], | ||
| threadId: `ai-review-${input.pr.number}`, | ||
| messages: [ | ||
| { | ||
| role: 'user', | ||
| content: [ | ||
| 'Review this pull request.', | ||
| 'Read the changed source files before you choose a verdict.', | ||
| 'If it is a bug fix and does not fix the claimed root cause, verdict is reject.', | ||
| 'If it is useful and needs listed bug or suggestion edits, apply those with edit_file, then verdict polish.', | ||
| 'If it is useful and clean, verdict is ready.', | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: TanStack/ai
Length of output: 3099
🏁 Script executed:
Repository: TanStack/ai
Length of output: 43233
🌐 Web query:
GitHub actions/checkout pull_request default ref merge commit documentation💡 Result:
When a GitHub Actions workflow is triggered by a pull_request event, the default behavior of the actions/checkout action is to check out the merge commit that GitHub has created for that pull request [1][2][3]. This is the commit that would result from merging the pull request branch into the base branch [1]. The actions/checkout action defaults the ref parameter to the reference or SHA that triggered the workflow [4][5][6]. For a pull_request event, this SHA points to the test merge commit created by GitHub, rather than the HEAD of the pull request branch [1][3]. If you prefer to check out the head of the pull request branch instead of the merge commit, you can explicitly set the ref parameter in your workflow configuration [4][5]: - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} This ensures that the action checks out the specific commit at the tip of your pull request branch [5]. This behavior is intentional to provide a testing environment that represents the state of the code after the pull request is merged [1]. Using the merge commit allows you to verify that the changes integrate correctly with the target branch before the merge actually occurs [1][7].
Citations:
Authorization Bypass (CWE-284)
Reachability: External · Exploitability: Moderate
Preserve the contributor trust guard for this secret-bearing job.
actions/checkoutchecks out the pull request merge commit by default. Therefore,pnpm ai-reviewexecutes pull request-controlled code. The runner passesXAI_API_KEYinto a local-process sandbox whose source and working directory are the PR worktree. A newly eligible author can modify executed code and exfiltrate the secret.Restore the previous author-association exclusions, or prevent pull request-controlled code from running with these secrets.
🤖 Prompt for AI Agents