feat(kit): audit context + artifact leg, driver-agents pin bump (v1.8.0) - #24
Conversation
…it pipeline (v1.8.0) Kit-only release. The provisioning step now exports SHOPIFY_AUDIT_CONTEXT (ticket resolved from the issue body's Bonsai uuid, closingIssuesReferences fallback on PR rails; issue ref + run URL + host), and a final if:always() upload-artifact step ships the runner's throwaway audit log to the box's nightly collector (run_attempt in the name — immutable artifacts collide across re-run attempts without it). DRIVER_AGENTS_REF -> 0bbb125 in both kit files (lockstep): the tool's context merge + audit-publish.sh.
WalkthroughThe workflows now pin the audit-pipeline revision, export Shopify audit context, and upload audit logs with rerun-safe names. The README documents these changes and identifies ChangesShopify audit pipeline
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@templates/github/claude.yml`:
- Around line 261-265: Update the GraphQL query in the TICKET assignment to
retrieve all linked closing issue bodies instead of only the first node, then
search the combined bodies with UUID_RE and retain the first matching ticket.
Preserve the existing empty fallback when no linked issue contains a UUID.
- Around line 257-258: Bound both best-effort GitHub lookups in the TICKET
extraction and GraphQL fallback paths by wrapping each gh api invocation with a
30-second timeout or equivalent supported wrapper. Preserve the existing
pipelines and ensure either timeout still falls back to an empty TICKET value.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 227a40f2-201c-4b0c-9816-effdff295503
📒 Files selected for processing (3)
README.mdtemplates/github/claude.ymltemplates/github/shopify-tool-smoke.yml
| TICKET="$(gh api "repos/$GITHUB_REPOSITORY/issues/$ISSUE_NUMBER" --jq '.body // ""' 2>/dev/null \ | ||
| | grep -oE "$UUID_RE" | head -1 | cut -c6-)" || TICKET="" |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
gh version
if gh help api 2>&1 | grep -q -- '--timeout'; then
echo "Use the CLI timeout explicitly."
else
echo "Keep timeout(1) around each gh api call."
fiRepository: DriverDigital/workflows
Length of output: 281
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "Candidate file:"
fd -a 'claude\.yml$' . | sed 's#^\./##' | head -20
echo
echo "Relevant lines around GitHub API calls:"
FILE="$(fd 'claude\.yml$' templates/github | head -1)"
if [ -n "${FILE:-}" ]; then
wc -l "$FILE"
sed -n '240,275p' "$FILE" | cat -n -v
fi
echo
echo "Search for timeout handling in workflow:"
rg -n "TIMEOUT|timeout|gh api|gh graphql|gh api " templates/github/claude.yml || true
echo
echo "Check whether gh help api mentions '--timeout' in help text:"
gh help api 2>&1 | sed -n '1,220p' | grep -n -- '--timeout' || trueRepository: DriverDigital/workflows
Length of output: 4570
🌐 Web query:
GitHub CLI gh api default timeout no timeout documentation
💡 Result:
The GitHub CLI gh api command does not provide a flag or configuration option to explicitly set or disable a request timeout [1][2][3]. The official documentation for gh api includes various flags for controlling headers, methods, pagination, and caching, but it does not mention a timeout parameter [1][3]. Because gh api uses the standard Go net/http client internally [4][5], it relies on the default timeout behaviors of that library or the underlying system environment. There is no supported way to specify "no timeout" via the command line for gh api. If you encounter timeout errors, they are typically handled at the network or system level rather than through the gh interface [6].
Citations:
- 1: https://cli.github.com/manual/gh_api
- 2: https://man.archlinux.org/man/gh-api.1.en.txt
- 3: https://cli.github.com/manual/gh_help_reference
- 4: https://github.com/cli/cli/blob/3ad29588b8bf9f2390be652f46ee4ef75b875b03/api/http_client.go
- 5: https://github.com/cli/cli/blob/5d3c2ba5691f4cb8388710c578eeeadf216eec96/api/client.go
- 6: error using api: Post "https://api.github.com/graphql": net/http: TLS handshake timeout cli/cli#1761
🌐 Web query:
GitHub CLI cli cli 2.96.0 api http_client.go request timeout DialTimeout
💡 Result:
In the GitHub CLI (gh), HTTP request handling—including timeouts and connection behavior—is orchestrated through the api package, specifically utilizing api/http_client.go [1][2][3]. The api/http_client.go file does not define a custom DialTimeout directly within its own logic; instead, it leverages the standard library net/http client via a wrapper provided by ghAPI (the CLI's internal API client library) [1][2]. The NewHTTPClient function initializes this client with various configuration options, such as authentication, logging, and caching [1][4]. When a network connection fails, such as during a dial tcp operation, the error is typically bubbled up from the underlying Go net/http transport [5]. Because the GitHub CLI relies on standard Go HTTP clients, connection-level timeouts (like DialTimeout) and request-level timeouts are governed by the http.Client configuration [6]. Key aspects of how the CLI handles timeouts include: 1. Standard Library Behavior: The http.Client used by the CLI inherits standard Go behavior where a Timeout field (if set) covers the entire request lifecycle, including connection, redirect, and reading the response body [6]. 2. Error Handling: The CLI has evolved to handle timeouts more explicitly to avoid confusing users. For example, recent improvements have introduced specific TimeoutError types or improved error messages to distinguish between genuine timeouts and other failures like authentication issues or 5XX server errors [7][8][9]. 3. Proxy and Network Issues: Many reported "connection timeout" errors in the GitHub CLI are often attributable to local network environments, such as proxy configurations or, in some cases, failures in local keyring/authentication lookups that mimic network failures [7][5]. If you are investigating a specific timeout issue, it is recommended to check the environment for proxy settings or authentication failures, as these are common sources of "i/o timeout" or "dial tcp" errors [7][5].
Citations:
- 1: https://github.com/cli/cli/blob/3ad29588b8bf9f2390be652f46ee4ef75b875b03/api/http_client.go
- 2: https://github.com/cli/cli/blob/5d3c2ba5691f4cb8388710c578eeeadf216eec96/api/http_client.go
- 3: https://github.com/cli/cli/tree/trunk/api
- 4: https://fossies.org/linux/gh-cli/api/http_client.go
- 5: Github api : connection timeout cli/cli#8328
- 6: https://go.googlesource.com/go/+/master/src/net/http/client.go
- 7:
gh apisilently sends unauthenticated requests when keychain access fails cli/cli#13317 - 8: Add timeout error in
gh auth statuscli/cli#8337 - 9: codespace: Handle HTTP request retry interruption cli/cli#7846
Bound the GitHub API lookups.
The provisioning critical path uses gh api at lines 257-261, and gh api does not expose a supported timeout flag for these best-effort calls. A stalled request can consume the 90-minute job timeout before Claude starts. Wrap both the issue lookup and GraphQL fallback in timeout 30s or a comparable bounded wrapper while keeping the existing empty-ticket fallback.
Also applies to: 261-265
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@templates/github/claude.yml` around lines 257 - 258, Bound both best-effort
GitHub lookups in the TICKET extraction and GraphQL fallback paths by wrapping
each gh api invocation with a 30-second timeout or equivalent supported wrapper.
Preserve the existing pipelines and ensure either timeout still falls back to an
empty TICKET value.
| TICKET="$(gh api graphql \ | ||
| -f query='query($o:String!,$r:String!,$n:Int!){repository(owner:$o,name:$r){pullRequest(number:$n){closingIssuesReferences(first:1){nodes{body}}}}}' \ | ||
| -f o="${GITHUB_REPOSITORY%%/*}" -f r="${GITHUB_REPOSITORY#*/}" -F n="$ISSUE_NUMBER" \ | ||
| --jq '.data.repository.pullRequest.closingIssuesReferences.nodes[0].body // ""' 2>/dev/null \ | ||
| | grep -oE "$UUID_RE" | head -1 | cut -c6-)" || TICKET="" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate file =="
git ls-files | grep -F 'templates/github/claude.yml' || true
echo "== relevant lines =="
if [ -f templates/github/claude.yml ]; then
nl -ba templates/github/claude.yml | sed -n '220,285p'
fi
echo "== search UFO/UUID and SHOPIFY_AUDIT_CONTEXT usages =="
rg -n "UUID_RE|closingIssuesReferences|SHOPIFY_AUDIT_CONTEXT|bon[sS]ai|Bonsai|uuid=" templates/github/claude.yml .github . 2>/dev/null | head -200Repository: DriverDigital/workflows
Length of output: 268
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file excerpt using awk =="
awk '{printf "%6d:%s\n", NR, $0}' templates/github/claude.yml | sed -n '220,285p'
echo "== search UFO/UUID/audit context references =="
grep -n "UUID_RE\|closingIssuesReferences\|SHOPIFY_AUDIT_CONTEXT\|Bonsai\|bosai\|uuid=" templates/github/claude.yml || trueRepository: DriverDigital/workflows
Length of output: 10094
🌐 Web query:
GitHub GraphQL closingIssuesReferences first nodes issue pullRequest query
💡 Result:
The closingIssuesReferences field in the GitHub GraphQL API is a connection that retrieves a list of issues that may be closed by a specific pull request [1][2]. It is available on the PullRequest object and provides a way to programmatically identify linked issues without relying on regex parsing of pull request bodies [3][4]. Example GraphQL Query To fetch the issues closed by a pull request, you can use the following structure [5][6]: query GetClosingIssues($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { closingIssuesReferences(first: 100) { nodes { number title url repository { name owner { login } } } pageInfo { hasNextPage endCursor } } } } } Key Details Connection Type: It returns an IssueConnection [1]. Pagination: As a connection, it supports pagination arguments such as first, last, after, and before [1][2]. Arguments: first/last: Required to limit the number of nodes returned [1]. userLinkedOnly (Boolean): An optional argument that, if set to true, returns only issues that were manually linked to the pull request [1]. Node Fields: You can request various fields for each issue, including number, title, id, url, and repository information [7][8]. This field is commonly used in GitHub Actions and automation scripts (such as those using the GitHub CLI or custom JavaScript workflows) to automate labeling, tracking, or validating pull requests based on the issues they are intended to close [3][6][9].
Citations:
- 1: https://docs.github.com/en/graphql/reference/pulls
- 2: https://docs.github.com/en/enterprise-cloud@latest/graphql/reference/pulls
- 3: Simplify
closing-pr.jswithclosingIssuesReferencesGraphQL API mlflow/mlflow#21912 - 4: Support GraphQL closingIssuesReferences and closedByPullRequestsReferences PyGithub/PyGithub#3482
- 5: Expose issues linked-to/closed-by in `gh pr view`? cli/cli#7097
- 6: Add field to retrieve linked issues (
closingIssuesReferences) ingh pr view <number>cli/cli#10529 - 7: https://github.com/cli/cli/blob/trunk/api/query_builder.go
- 8: [gh pr view] Support
closingIssuesReferencesJSON field cli/cli#10544 - 9: https://github.com/mondeja/pr-linked-issues-action
Search all linked issue bodies for uuid=....
closingIssuesReferences(first:1) only reads the first linked issue. When a PR closes multiple issues and the first issue body contains no Bonsai UUID, SHOPIFY_AUDIT_CONTEXT omits the ticket even though another linked issue supplies it.
Suggested fix
- query($o:String!,$r:String!,$n:Int!){repository(owner:$o,name:$r){pullRequest(number:$n){closingIssuesReferences(first:1){nodes{body}}}}}
+ query($o:String!,$r:String!,$n:Int!){repository(owner:$o,name:$r){pullRequest(number:$n){closingIssuesReferences(first:100){nodes{body}}}}}
- --jq '.data.repository.pullRequest.closingIssuesReferences.nodes[0].body // ""'
+ --jq '.data.repository.pullRequest.closingIssuesReferences.nodes[].body // ""'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| TICKET="$(gh api graphql \ | |
| -f query='query($o:String!,$r:String!,$n:Int!){repository(owner:$o,name:$r){pullRequest(number:$n){closingIssuesReferences(first:1){nodes{body}}}}}' \ | |
| -f o="${GITHUB_REPOSITORY%%/*}" -f r="${GITHUB_REPOSITORY#*/}" -F n="$ISSUE_NUMBER" \ | |
| --jq '.data.repository.pullRequest.closingIssuesReferences.nodes[0].body // ""' 2>/dev/null \ | |
| | grep -oE "$UUID_RE" | head -1 | cut -c6-)" || TICKET="" | |
| TICKET="$(gh api graphql \ | |
| -f query='query($o:String!,$r:String!,$n:Int!){repository(owner:$o,name:$r){pullRequest(number:$n){closingIssuesReferences(first:100){nodes{body}}}}}' \ | |
| -f o="${GITHUB_REPOSITORY%%/*}" -f r="${GITHUB_REPOSITORY#*/}" -F n="$ISSUE_NUMBER" \ | |
| --jq '.data.repository.pullRequest.closingIssuesReferences.nodes[].body // ""' 2>/dev/null \ | |
| | grep -oE "$UUID_RE" | head -1 | cut -c6-)" || TICKET="" |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@templates/github/claude.yml` around lines 261 - 265, Update the GraphQL query
in the TICKET assignment to retrieve all linked closing issue bodies instead of
only the first node, then search the combined bodies with UUID_RE and retain the
first matching ticket. Preserve the existing empty fallback when no linked issue
contains a UUID.
Kit-only release closing the CI legs of the audit pipeline (design: driver-agents
docs/audit-data-model.md, agreed 2026-07-31; implementation merged as driver-agents #3).SHOPIFY_AUDIT_CONTEXTexport in the provisioning step: ticket (Bonsai uuid grepped from the ISSUE body — the same linkagebonsai-status-sync.ymluses;closingIssuesReferencesfallback on the @claude-on-a-PR rails), issue ref, run URL, host. Every tool call's audit line now says on whose behalf it ran, and the nightly publisher mapsticketinto the client-visible app-home trail.if: always(),actions/upload-artifactpinned @ v7.0.1): the runner's throwaway audit log reaches the box's nightly collector.github.run_attemptin the artifact name is load-bearing — immutable artifacts collide across re-run attempts without it, losing exactly the suspicious runs the trail most needs. Same step on the smoke test.DRIVER_AGENTS_REF→0bbb125in both kit files (lockstep).actionlint (with shellcheck) clean. Reviewed as part of the audit-pipeline adversarial round (18 agents, 4 lenses) — the ticket-attribution gap and artifact-collision findings from that round are what this closes.
Summary by CodeRabbit
New Features
Documentation