Skip to main content
ClaudeWave
Skill6 repo starsupdated today

verify-gate

The verify-gate skill runs a mandatory pre-release checklist for the Piprail SDK and MCP server: TypeScript type-checking on source and tests separately, running the Vitest suite, building the SDK bundle, and grep-scanning for unintended non-EVM chain library imports that would break lazy-loading guarantees. Use this before committing, merging, or releasing to ensure the codebase meets architectural standards and maintains chain-agnostic protocol layers.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/piprail/piprail /tmp/verify-gate && cp -r /tmp/verify-gate/.claude/skills/verify-gate ~/.claude/skills/verify-gate
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# The verification gate

Nothing is "done" until this is green. It's a superset of the gate `prepublishOnly` runs (plus the lazy-chunk grep below),
and CI runs the same steps, so a red gate also fails CI and a release. Run it from the **repo root**:

```bash
npm run typecheck                       # SDK + MCP src type-check (tsc --noEmit)
npm run typecheck:test -w @piprail/sdk  # src + TESTS type-check together
npm run test:sdk                        # vitest run — the canonical contract
npm run build:sdk                       # tsup build succeeds
# Lazy-chunk invariant — the EVM bundle must pull in NO non-EVM chain lib:
grep -E "from ?['\"]@(solana|ton|stellar)" sdk/dist/index.js   # → expect NO matches
```

If you touched the **MCP**, also run its own type-check-with-tests, suite, and build —
the root `typecheck` only covers MCP *src*, not its tests:
```bash
npm run typecheck:test -w @piprail/mcp   # MCP src + tests (CI runs this; root typecheck does NOT)
npm run test:mcp
npm run build:mcp
```
The MCP resolves `@piprail/sdk`'s built `dist`, so build (and even type-check) the SDK first:
`build:sdk` before `build:mcp`.

## Why each step
- **`typecheck`** — the public API + internals type-check. The protocol layer must
  stay chain-agnostic (no `viem`/`@solana`/etc. in `server.ts`/`client.ts`/`x402.ts`).
- **`typecheck:test`** — a SEPARATE pass because tests are excluded from the build,
  so plain `typecheck` won't catch a type error in `test/`. Easy to forget; don't.
- **`test:sdk`** — Vitest is the canonical contract. Behaviour changed? The test
  changed first.
- **`build:sdk`** — the bundle actually builds (tsup).
- **Lazy-chunk grep** — the headline architectural guarantee: naming a non-EVM chain
  lazy-loads its libs, so a pure-EVM install never downloads `@solana`/`@ton`/etc.
  A stray static import silently breaks that — the grep is the tripwire. Expect
  **zero** matches in `sdk/dist/index.js`.

## When it's red
Fix it before moving on — never commit, merge, or tag with any step red. A failing
`typecheck:test` usually means a new `test/<family>/` file drifted from the contract;
a lazy-chunk match means a driver leaked a static import into the shared/EVM path
(move it behind the family's lazy `import()`).

> Full rules: [`sdk/STANDARDS.md`](../../../sdk/STANDARDS.md) §6. To cut a release once
> this is green, see the **`release`** skill.