From 4cdb03b16483f37a1877757acd95f1bece699df8 Mon Sep 17 00:00:00 2001 From: IlyasRidhuan Date: Thu, 16 Jul 2026 14:33:08 +0000 Subject: [PATCH] add skills --- .claude/skills/bump-aztec-version/SKILL.md | 86 +++++++++++++++++ .claude/skills/release/SKILL.md | 105 +++++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 .claude/skills/bump-aztec-version/SKILL.md create mode 100644 .claude/skills/release/SKILL.md diff --git a/.claude/skills/bump-aztec-version/SKILL.md b/.claude/skills/bump-aztec-version/SKILL.md new file mode 100644 index 00000000..35734702 --- /dev/null +++ b/.claude/skills/bump-aztec-version/SKILL.md @@ -0,0 +1,86 @@ +--- +name: bump-aztec-version +description: >- + Upgrade this repo to a new aztec-packages version — bump every reference (all Nargo.toml + aztec-nr git tags/revs + every @aztec/* npm dep + config.aztecVersion), install the matching + toolchain, and validate the bump locally (compile, Noir tests, typecheck, build, dry-run). + Produces a validated branch ready to merge. Publishing is the separate `release` skill. + Use when adopting a new aztec-packages tag or commit. +--- + +# Bump the aztec-packages version + +Adopts a new `aztec-packages` version across the repo and proves it works locally. Output: a branch +that compiles, tests, typechecks, and builds against the new deps — ready to open a PR to `main`. +**Publishing (rc / production) is handled by the separate `release` skill** — this skill stops at a +merged, validated bump. + +## Step 0 — gather inputs (ask the user) +Use `AskUserQuestion` (or ask directly) for: +1. **Target version** — a **tag** (e.g. `v5.0.0`) or a **commit SHA** of `AztecProtocol/aztec-packages`. +2. **Source** — a **path to a local checkout** of aztec-packages, or the **GitHub repo** (`AztecProtocol/aztec-packages`). The source is for *diagnosis + toolchain*, not the dep URL (Nargo deps always point at the GitHub git URL). +3. Derive the **npm version**: for a tag `vX.Y.Z` → `X.Y.Z`; for a commit, find the matching published npm version (`npm view @aztec/aztec.js versions` — often a `-nightly.`/`-snapshot.` build) or confirm one exists. If none, stop and tell the user the npm packages aren't published for that commit. + +Verify the target exists before touching anything: +- local: `git -C cat-file -e ^{commit}` +- github: `gh api repos/AztecProtocol/aztec-packages/commits/ --jq .sha` +- npm: `npm view @aztec/aztec.js@ version` + +## Step 1 — bump the Noir deps (all `Nargo.toml`) +```bash +find . -name Nargo.toml -not -path '*/node_modules/*' +``` +In each, update **only** the deps whose `git = "https://github.com/AztecProtocol/aztec-packages/"` +(e.g. `aztec`, `serde`, `uint_note`, `balance_set`, `compressed_string`). For a tag set +`tag = "vX.Y.Z"`; for a commit set `rev = ""` (replacing the existing `tag`/`rev`). +**Do NOT touch** non-aztec-packages deps (e.g. `sha512`, `bignum`) — they version independently. + +## Step 2 — bump the npm deps (`package.json`) +- Every `@aztec/*` dependency (accounts, aztec.js, noir-contracts.js, protocol-contracts, pxe, stdlib, wallet-sdk, wallets, …) → the npm version. +- `config.aztecVersion` → the npm version (the `setup-aztec` CI action reads this to install the toolchain). +- The package's own `version` is the *release* version — bump it too if this repo tracks aztec (it does), else leave. +- **`@aztec-foundation/aztec-benchmark` is a separate package** (its own repo/release). Only bump it if a matching release exists; it declares `@aztec/*` as **peerDependencies**, so it must resolve to the same aztec version — mismatches cause duplicate-type errors (see Gotchas). + +## Step 3 — regenerate the lockfile + toolchain +```bash +yarn install # updates node_modules + yarn.lock to the new versions +aztec-up install # install the toolchain matching the target (do NOT rely on a stale nightly) +export PATH="$HOME/.aztec/current/bin:$PATH" +``` +Confirm: `aztec --version`. If a local aztec-packages checkout was given, its toolchain can be used instead. + +## Step 4 — local validation (prove the bump) +Run in order; stop and diagnose on the first failure: +```bash +yarn ccc # clean + compile + codegen against the new deps +yarn test:nr # Noir tests (aztec test) +# typecheck src + scripts (+ benchmarks if the benchmark dep resolves) via a temp tsconfig with noEmit +yarn format:check +yarn install --frozen-lockfile # lockfile matches package.json +yarn build # assembles export/ +(cd export/@aztec-foundation/aztec-standards && npm publish --dry-run --access public) # tarball sanity +# yarn test:js — only if a local network is up (aztec start --local-network); needs no npm creds +``` +**Diagnosing failures:** a compile/test break is often a real API change in the new aztec version, +not a repo bug. Use the **local aztec-packages checkout / `gh api` at the target ref** to diff the +relevant internals and fix. See Gotchas. + +## Step 5 — hand off +When everything is green: commit, open a PR to `main`, let CI pass, merge. Then invoke the +**`release`** skill to cut an `rc` prerelease and, once that's validated, the production release. + +--- + +## Gotchas (bump-time — check these first) +- **Toolchain mismatch.** The default local `aztec`/`nargo` is often an older nightly that can't parse + the target's aztec-nr (e.g. "Non-ASCII character in comment"). Always `aztec-up install `. +- **Hand-rolled reproductions of aztec internals break on API changes.** `src/escrow_contract/src/key_derivation.nr` + re-implements `deriveKeys`; when v5 added master message-signing/fallback keys, escrow addresses + stopped matching. If `get_escrow`/derivation tests fail, diff the aztec-packages key-derivation + constants/`PublicKeys` at the target ref and re-sync. Regenerate the hardcoded `get_test_vector` hashes. +- **v5 wallet API.** `createSchnorrAccount(secret, salt)` → now needs a 3rd `GrumpkinScalar` signing key; + `Wallet` context types may need `EmbeddedWallet`. Deploy scripts derive the secret from the signing key + (`deriveSecretKeyFromSigningKey`). +- **Benchmark peerDep / duplicate tree.** If `benchmarks/*.ts` typecheck shows `_branding` / + `.../aztec-benchmark/node_modules/@aztec/...` errors, the benchmark pulled a *second* `@aztec` tree — + it must be on a version whose `@aztec/*` are `peerDependencies` matching this repo's aztec version. diff --git a/.claude/skills/release/SKILL.md b/.claude/skills/release/SKILL.md new file mode 100644 index 00000000..7f103ec4 --- /dev/null +++ b/.claude/skills/release/SKILL.md @@ -0,0 +1,105 @@ +--- +name: release +description: >- + Publish this repo to npm via the tag-driven release.yml — both rc prereleases + (X.Y.Z-rc.N → `rc` dist-tag) and production releases (X.Y.Z → `latest`). Stamps and + validates the version, pushes a `v*` tag, and verifies the publish (dist-tag, provenance, + smoke install). Always rehearse with an rc before a production tag. Use to cut an rc or a + final release. +--- + +# Release (rc prerelease or production) + +One flow for both. The tag-driven `release.yml` (`on: push tags v*`) derives the dist-tag from the +version: `-rc.N` → `rc`, else `latest`. The `rc` is a **rehearsal** for the immutable production +publish — always do it first. Assumes the version bump is already merged to `main` (see the +`bump-aztec-version` skill). + +## Preconditions (state them; don't assume) +- Fork workflows enabled; `NPM_TOKEN` in the `Production` environment with publish+**create** rights + for the package scope; workflows on an available runner (standard `ubuntu-latest`); `v*` tag-push rights. + +## Step 1 — pick mode + version (ALWAYS ASK — never infer) +**Always ask the user which release to cut** (use `AskUserQuestion`); never assume the mode from prior +context or conversation. This is a hard-to-reverse publish — the user chooses rc vs production every time. +- **rc rehearsal:** `X.Y.Z-rc.N` (do this first). Next `N` if a prior rc tag exists (`git ls-remote --tags origin`). +- **production:** `X.Y.Z` (only after a green rc). + +## Step 2 — stamp the version (⚠️ from the repo ROOT, never `export/`) +`export/…` is a gitignored build artifact with its own trimmed `package.json`; `npm version` there is +a silent no-op on the real package. Always start with `cd "$(git rev-parse --show-toplevel)"`. + +- **rc:** throwaway branch off `main` carrying the bump (keeps `main` at `X.Y.Z`): + ```bash + cd "$(git rev-parse --show-toplevel)" + git checkout main && git pull + git checkout -b rehearse/vX.Y.Z-rc.N + npm version X.Y.Z-rc.N --no-git-tag-version # edits the tracked ROOT package.json + git commit -am "chore: rehearse X.Y.Z-rc.N" + ``` +- **production:** `main` is already `X.Y.Z` — no bump, no branch; you'll tag `main` directly. + +## Step 3 — MANDATORY pre-tag guard (both modes) +Locally reproduce `release.yml`'s `tag == package.json` check *before* pushing the tag (this is the +assertion that fails the run on a mismatch): +```bash +cd "$(git rev-parse --show-toplevel)" +TARGET="X.Y.Z-rc.N" # the version you're releasing: X.Y.Z (production) or X.Y.Z-rc.N (rc) +case "$TARGET" in *-*) DIST="${TARGET#*-}"; DIST="${DIST%%.*}";; *) DIST="latest";; esac # rc/beta/... | latest — mirrors release.yml +echo "releasing v$TARGET → dist-tag '$DIST'" +[ "$(node -p "require('./package.json').version")" = "$TARGET" ] || { echo "ABORT: root package.json != $TARGET (bump didn't land — wrong dir / edited export/?)"; exit 1; } +git diff --quiet HEAD -- package.json || { echo "ABORT: bump uncommitted — the tag must point at the committed bump"; exit 1; } +grep -q "runs-on: ubuntu-latest$" .github/workflows/release.yml || echo "WARN: release.yml runner may be wrong (rebase onto main?)" +``` + +## Step 4 — tag & push +⚠️ **STOP — the tag push is the point of no return.** It fires `release.yml`, which publishes to npm, +and npm versions are **immutable**. Before running the push, show the user the exact `TARGET`, `DIST`, +and target commit, and get explicit confirmation. Do **not** push on your own initiative — even for an +rc. (The local tag/guard steps are safe to run first; only the `git push origin` line is gated.) +```bash +git tag -d "v$TARGET" 2>/dev/null; git push origin ":refs/tags/v$TARGET" 2>/dev/null # clear any stale/orphaned tag +git tag "v$TARGET" && git push origin "v$TARGET" # fires release.yml (tag-triggered; uses the file at this commit) +``` +Approve the `Production` environment run if reviewers are set. + +## Step 5 — verify, THEN report +Watch (`gh run watch`). The publish step succeeding (`+ pkg@ver`, provenance signed) is the source of +truth — the publish is immutable. Then verify the artifact (use `--prefer-online` to dodge cache/lag): +```bash +npm view @aztec-foundation/aztec-standards@"$TARGET" version --prefer-online # exists +npm view @aztec-foundation/aztec-standards dist-tags --prefer-online # $DIST -> $TARGET (see latest gotcha) +cd "$(mktemp -d)" && npm init -y >/dev/null && npm i --prefer-online @aztec-foundation/aztec-standards@"$DIST" +``` +For production `DIST=latest`, so `@latest` is what a plain `npm i @aztec-foundation/aztec-standards` resolves to. +Report success once the publish step is green (+ provenance) and the version resolves. A red +*smoke* step alone (propagation lag) is not a failed release — confirm the publish step + `npm view`. + +**Order across releases:** rc first (`DIST=rc`, rehearsal), then production (`DIST=latest`) once it's green. + +--- + +## Gotchas (release-time — check these first) +- **Run from the repo ROOT, never `export/`.** That dir is a gitignored build artifact with its own + trimmed `package.json`; `npm version` there is a no-op (`npm error Version not changed`) and leaves the + tag mismatched against the real version → `release.yml` validation fails. Step 3's guard catches it. +- **Registry propagation lag (esp. first publish).** A just-published version — particularly a package's + first-ever publish — can take minutes to resolve; an immediate `npm install` 404s. Don't fail the + release on a smoke miss (warn), and use `--prefer-online` to bypass the negative cache. Your *local* + npm may also cache the 404 — re-check with `npm view … --prefer-online`. +- **The first publish claims `latest`.** npm sets `latest` on a package's first-ever publish regardless of + `--tag`, so an `rc` rehearsal on a brand-new package leaves `latest` pointing at the rc. It self-corrects + when the stable `X.Y.Z` publishes; you can't `dist-tag rm latest` (a package must have one). Don't + announce the package until the stable is out. +- **Runners + fork state.** A GitHub fork has workflows disabled by default (enable in the Actions tab). + Target `ubuntu-latest`; don't assume custom/larger-runner labels (e.g. `ubuntu-latest-m`) exist — jobs + stuck `queued` are the symptom. +- **Pin CI to real tags.** Reusable-workflow refs (aztec-ci-actions / aztec-benchmark) should be pinned to a + released tag SHA (with a `# vX` comment), not a transient `main` HEAD — a pre-re-scope commit can still + `require('@defi-wonderland/…')`. +- **npm is immutable.** Always rehearse with an `rc` before the final tag. `release.yml` publishes + idempotently (re-running a tag re-points the dist-tag instead of erroring) and smoke-tests, so a failed + run is safe to re-trigger. +- **Provenance.** `release.yml` publishes with `--provenance` (needs `id-token: write` + `repository.url` + matching the running repo). The `rc` run is the first to exercise it; a Sigstore transparency-log line + in the publish output confirms it worked.