Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
fad6d5c
fix: interactions clean up (#21933)
Thunkar Mar 24, 2026
46ede19
fix(stdlib): decode `EthAddress`, `FunctionSelector` and wrapped fiel…
benesjan Mar 24, 2026
e81be61
wip
Thunkar Mar 24, 2026
81b641d
fix: bot gas estimations (#21945)
Thunkar Mar 24, 2026
e1ab32e
Merge branch 'merge-train/fairies' of github.com:AztecProtocol/aztec-…
Thunkar Mar 24, 2026
55a00be
fixes
Thunkar Mar 24, 2026
23eaeed
refactor(aztec-nr): use logging wrappers in compute_note_hash_and_nul…
nchamo Mar 24, 2026
403e8f7
feat: add error page mapping for incompatible oracles (#21943)
mverzilli Mar 24, 2026
c02d4a4
fix(pxe): robust error handling in message processing (#21093)
benesjan Mar 24, 2026
f00d2df
fix: make PXE#getSyncedBlockHeader a concurrency=1 job to prevent IDB…
mverzilli Mar 24, 2026
7026f9f
fix(aztec-up): validate semver in uninstall to prevent path traversal…
nchamo Mar 24, 2026
3d32a8f
fix(aztec-up): add truncation protection to install scripts (#21896)
nchamo Mar 24, 2026
0587d3c
fix: use llvm-objdump-20 for Mach-O re-signing in version injection (…
ludamad Mar 24, 2026
b15d7f2
chore: Fix nightly debug vk check (#21957)
federicobarbacovi Mar 24, 2026
1683d61
feat: SRS point compression - download 50% less CRS data (#21112)
johnathan79717 Mar 24, 2026
61de64f
chore: mainnet env
alexghr Mar 24, 2026
a697806
fix: add pull-requests write permission to ci-external workflow
johnathan79717 Mar 24, 2026
5f02a05
fix: add rc/testnet version detection to API reference pages
critesjosh Mar 24, 2026
2613ec1
fix: add rc/testnet version detection to API reference pages (#21966)
critesjosh Mar 24, 2026
f49661e
fix: add pull-requests write permission to ci-external workflow (#21965)
ludamad Mar 24, 2026
b42c0ec
feat: merge-train/spartan (#21889)
AztecBot Mar 24, 2026
67baaf3
feat: merge-train/barretenberg (#21962)
AztecBot Mar 24, 2026
af20c18
fix: wallet-sdk iframe handler improvements
Thunkar Mar 24, 2026
b980dd1
comments
Thunkar Mar 24, 2026
7b9c52d
fix
Thunkar Mar 24, 2026
d46d672
feat(docs): add aave tutorial
sklppy88 Mar 24, 2026
35f54de
feat(docs): add aave tutorial (#21048)
AztecBot Mar 24, 2026
3d0045c
docs: document EmbeddedWallet automatic gas estimation and private au…
critesjosh Mar 25, 2026
18a3a7e
docs: document EmbeddedWallet automatic gas estimation and private au…
AztecBot Mar 25, 2026
410cd93
chore: pre-audit of AVM GetContractInstance gadget and opcode (#21684)
dbanks12 Mar 25, 2026
82beed0
fix: deploy-staging-public waits for any semver tag instead of releas…
AztecBot Mar 25, 2026
3029216
feat!: scoped capsules (#21533)
mverzilli Mar 25, 2026
9a0080c
feat: merge-train/fairies (#21936)
AztecBot Mar 25, 2026
dc6a69f
chore: mainnet env (#21961)
PhilWindle Mar 25, 2026
5d31ab1
refactor: address PR review comments - type predicate, Set-based trac…
AztecBot Mar 25, 2026
330f027
feat(aztec-nr): add initialization check to utility functions (#21751)
nchamo Mar 25, 2026
9cf41af
refactor(aztec-nr): remove storage from init_test_contract (#21996)
nchamo Mar 25, 2026
a252184
chore: Remove Noir builtin comptime mutable methods from macros
jfecher Mar 25, 2026
bfec44a
fix: cache uncompressed CRS after first decompression
johnathan79717 Mar 25, 2026
5de59a7
chore: Remove Noir builtin comptime mutable methods from macros (#21801)
vezenovm Mar 25, 2026
202efce
chore: remove claude file (#22012)
nchamo Mar 25, 2026
1aea63f
chore: disable flaky docs/examples execute test
johnathan79717 Mar 25, 2026
228f4c0
chore: disable flaky docs/examples execute test (#22013)
AztecBot Mar 25, 2026
9fc5ddd
fix: cache uncompressed CRS after first decompression (#22002)
johnathan79717 Mar 25, 2026
31782b8
chore: re-enable docs/examples execute test, disable only aave_bridge
critesjosh Mar 25, 2026
b0090ff
refactor!: more consistent oracle names (#22018)
mverzilli Mar 25, 2026
1c74bf6
feat(aztec-nr)!: app-silo getSharedSecret oracle (#22020)
nchamo Mar 25, 2026
0097d11
fix: disallow infinite pubkeys (#22026)
nventuro Mar 25, 2026
2d9fd01
feat: aztecnr log prefixing (#22027)
nventuro Mar 25, 2026
ecd12c5
fix: deploy-staging-public waits for any semver tag instead of releas…
PhilWindle Mar 25, 2026
8c88e11
feat(aztec-nr)!: domain-separated tags on log emission (#21910)
nchamo Mar 26, 2026
93d06d5
feat: merge-train/fairies (#21994)
benesjan Mar 26, 2026
f1be5f5
chore: re-enable docs/examples execute test, disable only aave_bridge…
critesjosh Mar 26, 2026
823c5c9
feat: iframe wallets sdk (#21978)
Thunkar Mar 26, 2026
669e92b
chore: error in honk rec constraint creation for bad proof size (#21974)
ledwards2225 Mar 26, 2026
dc60288
Merge branch 'next' into merge-train/avm
IlyasRidhuan Mar 26, 2026
8acb1c5
fix(spartan): add preStartScript to blob-sink to fetch bootstrap nodes
alexghr Mar 26, 2026
b5f7209
feat: merge-train/avm (#21982)
AztecBot Mar 26, 2026
1fc9801
fix(spartan): add preStartScript to blob-sink to fetch bootstrap node…
alexghr Mar 26, 2026
82a2cbf
chore: rename pxe-side oracle implementations (#22044)
mverzilli Mar 26, 2026
593b6e8
docs: document AVM cryptographic compatibility for public vs private
critesjosh Mar 26, 2026
096a778
docs: document AVM cryptographic compatibility for public vs private …
AztecBot Mar 26, 2026
b365b45
fix(avm)!: data copy read padding (#21921)
IlyasRidhuan Mar 26, 2026
3b1879a
chore: merge next into merge-train/barretenberg (#22049)
johnathan79717 Mar 26, 2026
3b53c04
refactor: use Make targets for ci-barretenberg CI paths (#22061)
johnathan79717 Mar 26, 2026
fa49d9f
feat: merge-train/barretenberg (#22041)
AztecBot Mar 26, 2026
f01a05c
Merge branch 'next' into merge-train/avm
Mar 26, 2026
38e2192
Merge branch 'next' into merge-train/fairies
Mar 26, 2026
9eac21d
chore(acir_formal_proofs): fix and re-run shl/shr
defkit Mar 26, 2026
264c3cc
chore(acir_formal_proofs): fix and re-run shl/shr (#21938)
AztecBot Mar 26, 2026
ce3a495
Merge branch 'next' into merge-train/avm
Mar 26, 2026
53014a8
Merge branch 'next' into merge-train/fairies
Mar 26, 2026
e7fc502
fix: CRS tests work without compressed data on disk (#22066)
johnathan79717 Mar 26, 2026
f057992
fix(pxe): warn and return first log instead of throwing on ambiguous …
nchamo Mar 26, 2026
ece7eb5
chore: more robust padding in gemini (#21970)
iakovenkos Mar 26, 2026
102bfdd
feat: merge-train/fairies (#22048)
AztecBot Mar 26, 2026
7d2aa8c
fix(pxe): warn and return first log instead of throwing on ambiguous …
nventuro Mar 26, 2026
0f0c471
Merge branch 'next' into merge-train/avm
Mar 26, 2026
7495c03
Merge branch 'next' into merge-train/barretenberg
Mar 26, 2026
abf1108
fix(avm)!: sha256 pre-audit (#22001)
jeanmon Mar 26, 2026
7a97803
feat(aztec-up): default install version to latest instead of nightly …
nchamo Mar 26, 2026
0825643
fix(aztec-up): always reinstall noirup and foundryup bootstrappers (#…
nchamo Mar 26, 2026
a135b4f
fix(aztec-up): show installed version after install (#21822)
nchamo Mar 26, 2026
86e1a8d
Merge branch 'next' into merge-train/avm
Mar 26, 2026
1486541
Merge branch 'next' into merge-train/barretenberg
Mar 26, 2026
6beb4b7
Merge branch 'next' into merge-train/fairies
Mar 26, 2026
b5911e4
feat: merge-train/avm (#22059)
jeanmon Mar 26, 2026
63d9d60
chore: Update Noir to nightly-2026-03-26
Mar 26, 2026
26c1064
Merge branch 'next' into merge-train/barretenberg
Mar 26, 2026
642bcc2
Merge branch 'next' into merge-train/fairies
Mar 26, 2026
59a8cee
feat(aztec-up): decouple infra assets from toolchain VERSION (#22078)
nchamo Mar 26, 2026
5f80cf2
feat(aztec-up): add versioned aliases for multi-major version support…
nchamo Mar 26, 2026
2630864
feat(aztec-up): auto-update before install with staleness check (#21866)
nchamo Mar 26, 2026
b0c625c
refactor: name ECCVM subrelation indices with enums
Mar 25, 2026
e5ee2db
add static_assert(NUM_SUBRELATIONS == SUBRELATION_PARTIAL_LENGTHS.siz…
Mar 26, 2026
5c5ebcb
improve ECCVM subrelation enum names for accuracy and clarity
Mar 26, 2026
fda15ca
chore: Update Noir to nightly-2026-03-26 (#21876)
vezenovm Mar 26, 2026
3c1f54c
chore: name ECCVM subrelation indices with enums (#22003)
notnotraju Mar 26, 2026
f5eb525
Merge branch 'next' into merge-train/fairies
Mar 26, 2026
a524caa
Merge branch 'next' into merge-train/fairies
Mar 26, 2026
6d7d484
fix(aztec-up): pass VERSION to per-version installer and fix release …
nchamo Mar 26, 2026
e93b827
fix(pxe): warn when block header unavailable for proven/finalized events
benesjan Mar 26, 2026
7472aa9
random cleanups
benesjan Mar 26, 2026
49c0f44
feat: asserts that aztec dep version matches cli
benesjan Mar 27, 2026
9ef977d
feat: asserts that aztec dep version matches cli (#21245)
AztecBot Mar 27, 2026
8b7a362
feat: migrate claudebox CI to new format — SSH tunnel + direct profil…
AztecBot Mar 27, 2026
2462e72
Merge branch 'next' into merge-train/fairies
Mar 27, 2026
cf1a239
fix: remove aztec-audit/noir-audit profiles from CI (not yet available)
AztecBot Mar 27, 2026
83d7847
Merge branch 'next' into merge-train/fairies
Mar 27, 2026
e2c4d83
feat: merge-train/fairies (#22074)
AztecBot Mar 27, 2026
847ce95
fix(pxe): warn when block header unavailable for proven/finalized eve…
benesjan Mar 27, 2026
88ed079
Merge remote-tracking branch 'origin/next' into ag/merge
alexghr Mar 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
23 changes: 22 additions & 1 deletion .claude/agents/network-logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,31 @@ You can read this output directly — no parsing needed.
--format='table[no-heading](timestamp, resource.labels.pod_name, jsonPayload.message.slice(0,150))'
```

## Cluster Mapping

Aztec runs two GKE clusters:

| Cluster | Aztec namespaces |
|---------|-----------------|
| `aztec-gke-private` | `mainnet` (ignition — active), `next-net`, `staging-ignition`, `staging-public`, and various test/scenario namespaces |
| `aztec-gke-public` | `mainnet` (public — currently in standby), `testnet`, and other public-facing infrastructure |

**Important: `mainnet` exists in BOTH clusters.**
- The **private** cluster's `mainnet` runs the **ignition** network (active, fisherman mode).
- The **public** cluster's `mainnet` is the next rollup upgrade (currently in standby, waiting for L1 contract alignment). It also runs in fisherman mode.

When querying `mainnet`, you MUST include a `resource.labels.cluster_name` filter to disambiguate:
- If the user says "mainnet" without qualification, query the **private** cluster (ignition) by default — it's the active one.
- If the user says "mainnet public", "public cluster mainnet", or "mainnet on public", query the **public** cluster.
- If uncertain, query **both** clusters in parallel and report results separately.

For all other namespaces, the cluster filter is optional but recommended for clarity.

## GCP Log Structure

Aztec network logs use:
- `resource.type="k8s_container"`
- `resource.labels.cluster_name` — the GKE cluster (`aztec-gke-private` or `aztec-gke-public`)
- `resource.labels.namespace_name` — the deployment namespace
- `resource.labels.pod_name` — the specific pod
- `resource.labels.container_name` — usually `aztec`
Expand All @@ -92,7 +113,7 @@ Pods follow the pattern `{namespace}-{component}-{index}`:
## Deployment-Specific Notes

- **next-net** redeploys every morning at ~4am UTC. Always use timestamp range filters (not `--freshness`) when querying next-net for a specific date, and expect logs to only cover a single instance of the network. Because next-net resets daily, its block height should start near 0 after ~4am UTC. If you are running a morning healthcheck and the block height is unexpectedly large (e.g., hundreds or thousands), flag this as an error — it likely means the nightly redeploy failed and the network is running a stale instance.
- **mainnet** does not run sequencer validators. Instead, it runs infrastructure in **fisherman mode**: nodes simulate building a block for every slot but never actually submit the L1 transaction. This means you will see "built block" or similar messages but no "Published checkpoint" or L1 submission logs. Errors with hash `0xf3e591ac` are a known artifact of fisherman mode and are safe to ignore.
- **mainnet** (both private/ignition and public) does not run sequencer validators. Both deployments run in **fisherman mode**: nodes simulate building a block for every slot but never actually submit the L1 transaction. This means you will see "built block" or similar messages but no "Published checkpoint" or L1 submission logs. Errors with hash `0xf3e591ac` are a known artifact of fisherman mode and are safe to ignore. See the Cluster Mapping section above for how to disambiguate between the two mainnet deployments.

## Filter Building

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/ci3-external.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
runs-on: ubuntu-latest
# exclusive with ci3.yml, only run on forks.
if: github.event.pull_request.head.repo.fork
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
AZTEC_TOOLCHAIN_DEFAULT_MAJOR_VERSION: ${{ vars.AZTEC_TOOLCHAIN_DEFAULT_MAJOR_VERSION }}
# For automatic documentation updates via Claude Code
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
# Nightly test env vars.
Expand Down
187 changes: 85 additions & 102 deletions .github/workflows/claudebox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@ on:
description: 'Context link (e.g., PR URL, issue URL, external reference)'
required: false
type: string
profile:
description: 'Profile'
required: false
default: 'aztec'
type: choice
options: [aztec, barretenberg-audit, noir]
model:
description: 'Model'
required: false
default: 'sonnet'
type: choice
options: [sonnet, opus]
budget:
description: 'Budget in USD'
required: false
default: '1.00'
type: string
target_ref:
description: 'Git ref to checkout in the container (e.g., origin/backport-to-v4-next-staging)'
required: false
Expand All @@ -33,23 +50,19 @@ jobs:
if: github.event_name == 'issue_comment'
run: |
ASSOCIATION="${{ github.event.comment.author_association }}"
echo "Author association: $ASSOCIATION"
if [[ "$ASSOCIATION" != "OWNER" && "$ASSOCIATION" != "MEMBER" && "$ASSOCIATION" != "COLLABORATOR" ]]; then
echo "ERROR: User does not have write access (association: $ASSOCIATION)"
echo "ERROR: No write access ($ASSOCIATION)"
exit 1
fi
echo "Access granted."

- name: Add reaction
if: github.event_name == 'issue_comment'
env:
GH_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }}
run: |
gh api \
repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \
-f content='eyes' || true
gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions -f content='eyes' || true

- name: Setup SSH tunnel to ClaudeBox
- name: Setup SSH tunnel
env:
BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }}
run: |
Expand All @@ -58,18 +71,17 @@ jobs:
echo "${BUILD_INSTANCE_SSH_KEY}" | base64 --decode > ~/.ssh/build_instance_key
chmod 600 ~/.ssh/build_instance_key

# SSH tunnel: CI runner :4001 → bastion :3000 → (reverse tunnel) → claude-box :3001
ssh -f -N -L 4001:localhost:3000 \
# SSH tunnel: CI runner :4000 → bastion :3000 → (reverse tunnel) → claude-box :4000
ssh -f -N -L 4000:localhost:3000 \
-o StrictHostKeyChecking=no \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-o ConnectTimeout=15 \
-i ~/.ssh/build_instance_key \
ubuntu@ci.aztec-labs.com

# Wait for tunnel
for i in $(seq 1 15); do
if curl -s -o /dev/null --max-time 2 http://localhost:4001/ 2>/dev/null; then
if curl -s -o /dev/null --max-time 2 http://localhost:4000/health 2>/dev/null; then
echo "SSH tunnel ready"
exit 0
fi
Expand All @@ -84,13 +96,25 @@ jobs:
COMMENT_BODY: ${{ github.event.comment.body || '' }}
INPUT_PROMPT: ${{ inputs.prompt || '' }}
INPUT_LINK: ${{ inputs.link || '' }}
INPUT_PROFILE: ${{ inputs.profile || 'aztec' }}
INPUT_MODEL: ${{ inputs.model || 'sonnet' }}
INPUT_BUDGET: ${{ inputs.budget || '1.00' }}
INPUT_TARGET_REF: ${{ inputs.target_ref || '' }}
run: |
if [ -n "$INPUT_PROMPT" ]; then
PROMPT="$INPUT_PROMPT"
LINK="$INPUT_LINK"
echo "profile=$INPUT_PROFILE" >> "$GITHUB_OUTPUT"
echo "model=$INPUT_MODEL" >> "$GITHUB_OUTPUT"
echo "budget=$INPUT_BUDGET" >> "$GITHUB_OUTPUT"
echo "target_ref=$INPUT_TARGET_REF" >> "$GITHUB_OUTPUT"
else
PROMPT=$(printf '%s' "$COMMENT_BODY" | sed 's|^/claudebox[[:space:]]*||')
LINK=""
echo "profile=aztec" >> "$GITHUB_OUTPUT"
echo "model=sonnet" >> "$GITHUB_OUTPUT"
echo "budget=1.00" >> "$GITHUB_OUTPUT"
echo "target_ref=" >> "$GITHUB_OUTPUT"
fi

echo "link=$LINK" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -118,66 +142,45 @@ jobs:
-f body="$BODY" \
--jq '.id')
echo "run_comment_id=$COMMENT_ID" >> "$GITHUB_OUTPUT"
echo "Posted status comment: $COMMENT_ID"

- name: Run ClaudeBox
- name: Run session
timeout-minutes: 120
env:
CLAUDEBOX_URL: http://localhost:4001
CLAUDEBOX_API_SECRET: ${{ secrets.CLAUDEBOX_API_SECRET }}
CLAUDEBOX_URL: http://localhost:4000/${{ steps.parse.outputs.profile }}
CLAUDEBOX_TOKEN: ${{ secrets.CLAUDEBOX_API_SECRET }}
CLAUDEBOX_PROMPT: ${{ steps.parse.outputs.prompt }}
CLAUDEBOX_LINK: ${{ steps.parse.outputs.link }}
CLAUDEBOX_TARGET_REF: ${{ inputs.target_ref || '' }}
COMMENT_ID: ${{ github.event.comment.id || '' }}
RUN_COMMENT_ID: ${{ steps.status_comment.outputs.run_comment_id || '' }}
REPO: ${{ github.repository }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
AUTHOR: ${{ github.event.comment.user.login || github.actor }}
run: |
AUTH="Authorization: Bearer ${CLAUDEBOX_API_SECRET}"
echo "Creating payload..."
PAYLOAD=$(jq -n \
--arg prompt "$CLAUDEBOX_PROMPT" \
--arg user "$AUTHOR" \
--arg comment_id "$COMMENT_ID" \
--arg run_comment_id "$RUN_COMMENT_ID" \
--arg repo "$REPO" \
--arg run_url "$RUN_URL" \
--arg link "$CLAUDEBOX_LINK" \
--arg target_ref "$CLAUDEBOX_TARGET_REF" \
'{prompt: $prompt, user: $user, comment_id: $comment_id, run_comment_id: $run_comment_id, repo: $repo, run_url: $run_url, link: $link, target_ref: $target_ref}')
MODEL="${{ steps.parse.outputs.model }}"
BUDGET="${{ steps.parse.outputs.budget }}"
TARGET_REF="${{ steps.parse.outputs.target_ref }}"

echo "Sending payload..."
# Start session — returns 202 with log URL
RESPONSE=$(curl -sS -w "\n%{http_code}" \
-H "$AUTH" -H "Content-Type: application/json" \
-d "$PAYLOAD" "${CLAUDEBOX_URL}/run")
BODY=$(jq -n \
--arg prompt "$CLAUDEBOX_PROMPT" \
--arg model "$MODEL" \
--arg budget "$BUDGET" \
--arg target_ref "$TARGET_REF" \
'{prompt: $prompt, model: $model, costUSD: ($budget | tonumber), user: "github-actions", name: $prompt, targetRef: $target_ref}')

HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | head -n -1)
echo "Starting session on ${{ steps.parse.outputs.profile }}..."
RESP=$(curl -sf -X POST "$CLAUDEBOX_URL/sessions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $CLAUDEBOX_TOKEN" \
-d "$BODY")

if [ "$HTTP_CODE" -ge 400 ] 2>/dev/null; then
echo "ClaudeBox returned HTTP $HTTP_CODE: $BODY"
exit 1
fi
SID=$(echo "$RESP" | jq -r '.id // empty')
echo "Session: $SID"
echo "Status: https://claudebox.work/${{ steps.parse.outputs.profile }}/s/$SID"

LOG_URL=$(echo "$BODY" | jq -r '.log_url // empty')
SESSION_ID=$(basename "$LOG_URL")
echo "Session started: $LOG_URL"

echo "Session received, polling..."
# Poll until completed
while true; do
sleep 30
STATUS_BODY=$(curl -sS -H "$AUTH" "${CLAUDEBOX_URL}/session/${SESSION_ID}" 2>/dev/null || echo '{}')
sleep 10
STATUS_BODY=$(curl -sf "$CLAUDEBOX_URL/sessions/$SID" -H "Authorization: Bearer $CLAUDEBOX_TOKEN" || echo '{}')
STATUS=$(echo "$STATUS_BODY" | jq -r '.status // "unknown"')
echo "$(date -u +%H:%M:%S) status=$STATUS"
if [ "$STATUS" != "running" ]; then
EXIT_CODE=$(echo "$STATUS_BODY" | jq -r '.exit_code // 1')
echo "Session finished: status=$STATUS exit_code=$EXIT_CODE"
echo "Log: $LOG_URL"
exit "$EXIT_CODE"
fi
COST=$(echo "$STATUS_BODY" | jq -r '.costUSD // 0')
echo "$(date -u +%H:%M:%S) status=$STATUS cost=\$$COST"
case "$STATUS" in
completed) echo "Done. Cost: \$$COST"; exit 0 ;;
error|cancelled|budget_exhausted) echo "Failed: $STATUS"; exit 1 ;;
esac
done

claude-review:
Expand All @@ -189,7 +192,7 @@ jobs:
permissions:
contents: read
steps:
- name: Setup SSH tunnel to ClaudeBox
- name: Setup SSH tunnel
env:
BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }}
run: |
Expand All @@ -198,7 +201,7 @@ jobs:
echo "${BUILD_INSTANCE_SSH_KEY}" | base64 --decode > ~/.ssh/build_instance_key
chmod 600 ~/.ssh/build_instance_key

ssh -f -N -L 4001:localhost:3000 \
ssh -f -N -L 4000:localhost:3000 \
-o StrictHostKeyChecking=no \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
Expand All @@ -207,7 +210,7 @@ jobs:
ubuntu@ci.aztec-labs.com

for i in $(seq 1 15); do
if curl -s -o /dev/null --max-time 2 http://localhost:4001/ 2>/dev/null; then
if curl -s -o /dev/null --max-time 2 http://localhost:4000/health 2>/dev/null; then
echo "SSH tunnel ready"
exit 0
fi
Expand All @@ -230,24 +233,18 @@ jobs:
-f body="$BODY" \
--jq '.id')
echo "run_comment_id=$COMMENT_ID" >> "$GITHUB_OUTPUT"
echo "Posted review status comment: $COMMENT_ID"

- name: Trigger ClaudeBox review
- name: Trigger review session
timeout-minutes: 120
env:
CLAUDEBOX_URL: http://localhost:4001
CLAUDEBOX_API_SECRET: ${{ secrets.CLAUDEBOX_API_SECRET }}
CLAUDEBOX_URL: http://localhost:4000/aztec
CLAUDEBOX_TOKEN: ${{ secrets.CLAUDEBOX_API_SECRET }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_URL: ${{ github.event.pull_request.html_url }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
RUN_COMMENT_ID: ${{ steps.status_comment.outputs.run_comment_id || '' }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
REPO: ${{ github.repository }}
run: |
AUTH="Authorization: Bearer ${CLAUDEBOX_API_SECRET}"

PROMPT="Review PR #${PR_NUMBER}: ${PR_TITLE}
${PR_URL}

Expand All @@ -258,43 +255,29 @@ jobs:
Focus on non-obvious bugs: edge cases, concurrency, security, correctness, compatibility.
If you find a direct fix, create a PR. When done, call manage_review_labels(pr_number=${PR_NUMBER})."

PAYLOAD=$(jq -n \
BODY=$(jq -n \
--arg prompt "$PROMPT" \
--arg user "review/${PR_AUTHOR}" \
--arg run_comment_id "$RUN_COMMENT_ID" \
--arg repo "$REPO" \
--arg run_url "$RUN_URL" \
--arg link "$PR_URL" \
--arg profile "review" \
'{prompt: $prompt, user: $user, run_comment_id: $run_comment_id, repo: $repo, run_url: $run_url, link: $link, profile: $profile}')
'{prompt: $prompt, user: $user, model: "sonnet", costUSD: 1, name: $prompt}')

RESPONSE=$(curl -sS -w "\n%{http_code}" \
-H "$AUTH" -H "Content-Type: application/json" \
-d "$PAYLOAD" "${CLAUDEBOX_URL}/run")
RESP=$(curl -sf -X POST "$CLAUDEBOX_URL/sessions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $CLAUDEBOX_TOKEN" \
-d "$BODY")

HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | head -n -1)
SID=$(echo "$RESP" | jq -r '.id // empty')
echo "Review session: $SID"
echo "Status: https://claudebox.work/aztec/s/$SID"

if [ "$HTTP_CODE" -ge 400 ] 2>/dev/null; then
echo "ClaudeBox returned HTTP $HTTP_CODE: $BODY"
exit 1
fi

LOG_URL=$(echo "$BODY" | jq -r '.log_url // empty')
SESSION_ID=$(basename "$LOG_URL")
echo "Review session started: $LOG_URL"

# Poll until completed
while true; do
sleep 30
STATUS_BODY=$(curl -sS -H "$AUTH" "${CLAUDEBOX_URL}/session/${SESSION_ID}" 2>/dev/null || echo '{}')
STATUS_BODY=$(curl -sf "$CLAUDEBOX_URL/sessions/$SID" -H "Authorization: Bearer $CLAUDEBOX_TOKEN" || echo '{}')
STATUS=$(echo "$STATUS_BODY" | jq -r '.status // "unknown"')
echo "$(date -u +%H:%M:%S) status=$STATUS"
if [ "$STATUS" != "running" ]; then
EXIT_CODE=$(echo "$STATUS_BODY" | jq -r '.exit_code // 1')
echo "Review finished: status=$STATUS exit_code=$EXIT_CODE"
echo "Log: $LOG_URL"
# Don't fail the workflow on review errors — the review itself is informational
exit 0
fi
case "$STATUS" in
completed|error|cancelled|budget_exhausted)
echo "Review finished: $STATUS"
exit 0
;;
esac
done
Loading
Loading