diff --git a/.agents/lib/pr-review-base.md b/.agents/lib/pr-review-base.md index 5f495e33f..e43136b6c 100644 --- a/.agents/lib/pr-review-base.md +++ b/.agents/lib/pr-review-base.md @@ -78,7 +78,15 @@ For each unique package directory among the changed files (e.g. a file at `packa Use the Glob tool: `**/AGENTS.md` and `packages/*/*.md`. Filter to paths that prefix at least one changed file's directory. Files outside `packages/` use only items 1–4 of the root baseline (items 5–7 conditional as triggered). -After discovery, **print** the list of files read so the user can spot omissions: +### Detect conditional persona triggers + +Compute flags from the changed-files list. These flags drive which `kind: conditional` personas launch in Step 5: + +- `` — true if any changed file matches `.github/workflows/**`, `.github/actions/**`, `.changeset/**`, root or package `package.json` (when a `scripts.*publish*` / `scripts.*release*` field is touched), `pnpm-lock.yaml`, `pnpm-workspace.yaml`, `.npmrc`, OR if any changed file contains `changeset publish`, `npm publish`, `pnpm publish`, or `gh release create`. + +Add new flags here when introducing future conditional personas. Each `kind: conditional` persona file declares its `trigger:` placeholder in frontmatter; Step 5 launches it only when that flag is true. + +After discovery, **print** the list of files read AND the flag values so the user can spot omissions: ``` Context files read (N): @@ -87,133 +95,50 @@ Context files read (N): packages/morpho-sdk/AGENTS.md packages/morpho-sdk/src/actions/AGENTS.md ... + +Conditional flags: + HAS_CI_RELEASE: ``` ## Step 5: Launch parallel review agents -Launch ALL 7 review agents **in parallel** using the Agent tool (subagent_type: `"general-purpose"`). Shared per-agent contract: +Persona specs live in `.agents/personas/*.md`. Each file has frontmatter declaring `kind: baseline` (always fires) or `kind: conditional` (fires only when its `trigger:` flag is true), plus the prompt body. -- Each agent receives: full diff, full content of changed files (read from local FS), `` from Step 4, the repo path / branches. +Loop: + +1. Read every file in `.agents/personas/*.md`. +2. For each persona, decide whether to launch: + - `kind: baseline` → always launch. + - `kind: conditional` → launch only when the flag named in `trigger:` is true (see Step 4 for flag computation). +3. Launch ALL selected personas **in parallel** using the Agent tool (subagent_type: `"general-purpose"`). +4. Track `` = count of personas actually launched (baseline + any fired conditionals). + +Shared per-agent contract (applied uniformly to every launched persona): + +- Each agent receives: full diff, full content of changed files (read from local FS), `` from Step 4, the conditional flag values, the persona file body, the repo path / branches. - Per-package `AGENTS.md` rules refine the root for the specific package; the root wins on contradictions. - Agents must analyze the **full diff**, not just the latest commit. - Each agent **must return** a JSON array `[{severity: "critical"|"high"|"medium"|"low", file: "path", line: number, description: "what is wrong + how to fix"}]` OR an explicit error sentinel `{"agent_error": ""}` if it could not complete (the aggregator in Step 6 distinguishes "no findings" from "agent failed"). - **Stay in scope (avoid scope creep).** Focus on the diff: flag issues introduced by these changes, and issues in adjacent code only when the diff makes that adjacent code materially worse (e.g. a renamed function whose remaining callers now misbehave, a new code path that exposes an existing bug). Do NOT flag pre-existing issues in unchanged lines of changed files, propose unrelated refactors, suggest new features or abstractions, or recommend cleanups outside the PR's intent. When in doubt, omit — the reviewer is reviewing *this change*, not the file's history. - Only **actionable** findings — no praise, no summaries. -### Agent 1: Code Quality - -Focus: TypeScript strict mode, type safety, early returns, `as` assertions, duplication, naming, code smells, magic numbers, overly complex functions. - -Prompt must include: - -- Type safety issues (`any`, unsafe `as` assertions, missing generics) -- Error handling and edge cases -- Code smells (duplicated logic, overly complex functions, magic numbers) -- Early returns preferred over nested conditionals -- Naming conventions per the root `AGENTS.md` (and any per-package `AGENTS.md` for the file under review) -- Reference `AGENTS.md` (root, canonical), `MISSION.md`, the package's `AGENTS.md`, and `CONTRIBUTING.md` - -**Cross-file impact (critical for an SDK):** -- Changed exports from `packages//src/index.ts` — could break consumer code -- Function signature changes on public APIs (parameter add/remove/reorder/type-narrow) -- Renamed or removed exports -- API contract changes (return type, thrown error type, async-vs-sync) -- New deep imports into other packages (should go through `src/index.ts`) - -**Security:** -- Hardcoded secrets, tokens, private keys, RPC URLs with credentials -- Injection risks in any string-templated input (SQL-like queries, shell commands) -- Authentication bypass / authorization checks missing on entry points -- `eval`, `Function(...)` constructors, dynamic `import()` — flag any - -### Agent 2: Module & API Architecture - -Focus: package boundaries, public surface, type/import discipline, NodeNext compatibility. - -Prompt must include: - -- Public exports come from `packages//src/index.ts` only — no deep imports into other packages -- Relative imports include `.js` suffix (NodeNext) — e.g. `export * from "./market/index.js"` -- Prefer type-only imports where possible (`import type { Address } from "viem"`) -- Reuse SDK types for protocol values: `Address`, `MarketId`, `ChainId`, `BigIntish` -- `bigint` for onchain quantities and WAD-scaled rates (e.g. `92_0000000000000000n`) -- `as const` and `satisfies` for protocol lists and ABI literals (e.g. `BLUE_OPERATIONS as const`) -- Domain failures are typed `Error` subclasses with readonly inputs -- Edits to generated **inputs** (e.g. `graphql/*.gql`), not generated files (e.g. `src/api/sdk.ts`) -- No edits to build output under `lib/` -- Reference the root `AGENTS.md`, the package's `AGENTS.md` (and any nested `AGENTS.md`), and the package's own `package.json` `exports` field - -### Agent 3: Web3 Security - -Focus: Contract interactions, transaction parameters, wallet handling, permit flows, race conditions. **This is CRITICAL review territory.** - -Prompt must include: - -- Contract interactions: verify correct contract addresses, function signatures, and arguments -- Transaction parameters: check gas estimates, value transfers, and calldata encoding -- Reactivity concerns: can state changes cause unintended transaction parameters? -- Wallet connection: proper account handling and chain verification -- Hook usage: correct usage of wagmi hooks (useContractRead, useContractWrite, etc.) -- Error handling: transaction failures, reverts, and user rejections -- Race conditions in async operations -- Missing transaction confirmations or proper waiting for receipts -- Permit/deadline handling (avoid stale block timestamps) - -### Agent 4: Silent Failure Hunter - -Focus: Swallowed errors, missing error boundaries, empty catch blocks, unhandled promise rejections, missing loading/error states, dead code paths. - -Prompt must include: - -- Empty or overly broad catch blocks that swallow errors -- Missing error boundaries around async components -- Unhandled promise rejections (missing `.catch()` or try/catch) -- Missing loading states for async operations -- Missing error states for failed data fetches -- Silently ignored return values from critical operations -- Dead code paths that can never execute - -### Agent 5: Style & Conventions Compliance - -Focus: Biome compliance, import discipline, monorepo conventions. - -Prompt must include: - -- Biome clean: 2-space indentation, organized imports, no unused imports/variables (`pnpm lint`) -- Type-only imports where possible (`import type { ... }`) -- Relative imports use `.js` suffix in source files (NodeNext) -- No edits to generated files (e.g. `src/api/sdk.ts`) — change generated **inputs** instead -- No edits to build output under `lib/` -- Reuse of SDK types (`Address`, `MarketId`, `ChainId`, `BigIntish`) over local re-declarations -- Reference the root `AGENTS.md`, the package's `AGENTS.md`, and `biome.json` -- Changeset relevance: verify `.changeset/*.md` files are present when the PR changes published package source in a semver-relevant way. Allow patch changesets for JSDoc-only changes to published package source. Flag unnecessary changesets for repo metadata, non-API documentation-only, fixture-only, generated-output-only, or tests-only diffs; flag missing changesets for behavior-affecting published package source changes. - -### Agent 6: Documentation Analyzer - -Focus: JSDoc/TSDoc on public APIs and types in `packages//src/index.ts` and the files it re-exports. - -**Canonical JSDoc rules: `docs/jsdoc-style.md`** (operationalizes AGENTS.md §6 and MISSION.md goal #3 — AI-legibility). Include the contents of `docs/jsdoc-style.md` (or a faithful summary) so reviewers flag deviations from the canonical shape. - -Prompt must include: +### Current persona inventory -- The `docs/jsdoc-style.md` checklist (what needs JSDoc, what does not, the required block order, `@param` / `@returns` / `@throws` / `@example` rules, error-message phrasing). -- New or modified public exports re-exported from `packages//src/index.ts` must have JSDoc that conforms to `docs/jsdoc-style.md`. -- Doc comments accurate vs. the implementation (no stale references to renamed args, removed return values, changed throw behavior). -- Public types use semantic names — flag generic `T`, `U`, `Foo` where domain names exist. -- README / package-level doc files updated when the public API changes shape. -- `@example` blocks compile and follow the runnable-recipe shape from the style guide. +Baseline (always fire): -### Agent 7: Test Coverage Analyzer +- `code-quality.md` — type safety, code smells, naming, cross-file impact on SDK consumers, security primitives. +- `module-api-architecture.md` — package boundaries, public surface, NodeNext import discipline. +- `web3-security.md` — contract interactions, transaction params, permit flows, race conditions. +- `silent-failure-hunter.md` — swallowed errors, missing error states, dead code paths. +- `style-conventions.md` — Biome compliance, import discipline, changeset relevance. +- `documentation.md` — JSDoc on public exports per `docs/jsdoc-style.md`. +- `test-coverage.md` — missing tests for new code paths and onchain interactions. -Focus: missing or weak tests in `packages//test/` for changes in `packages//src/`. +Conditional: -Prompt must include: +- `ci-release-security.md` — fires when `` is true. Workflow injection, action pinning, permissions scopes, secret exposure, publish-flow integrity, lockfile drift. -- New public exports without a corresponding test file under `packages//test/` -- New code paths inside existing exports without test cases (branches, error paths, edge cases like zero/MAX_UINT256/negative bigints) -- Removed or modified public exports without tests updated -- Onchain code paths (any code calling `viem`/`wagmi` actions) — confirm there's at least one test that exercises the path against a fork or mock -- Snapshot or schema tests updated when generated outputs change +Adding a new persona = drop a new file under `.agents/personas/` with appropriate frontmatter. If conditional, also extend Step 4's flag detection. No edit to caller files needed. ## Step 6: Aggregate and deduplicate findings @@ -266,5 +191,6 @@ The caller (Step 7 of `/pr-review-ci` / `/pr-review-gh` / `/pr-review-local`) co - `` — sorted, deduplicated array of `{severity, file, line, description}`. - `` — count + names of agents that returned `agent_error` or malformed output. - `` — `{critical, high, medium, low}` totals. +- `` — count of personas that actually fired (baseline always-fire count + any conditional personas whose trigger flag was true). Used by the caller's report to phrase " of agents failed" correctly when conditional personas did not fire. The caller formats and routes these per its mode (CI verdict / GitHub COMMENT / terminal output). diff --git a/.agents/personas/ci-release-security.md b/.agents/personas/ci-release-security.md new file mode 100644 index 000000000..52e600f58 --- /dev/null +++ b/.agents/personas/ci-release-security.md @@ -0,0 +1,85 @@ +--- +name: ci-release-security +kind: conditional +trigger: +focus: GitHub Actions workflow injection, action pinning, workflow permissions, secret exposure, publish-flow integrity, Changesets/release-bot wiring, lockfile drift, dependency hygiene, .npmrc and pnpm-workspace settings. +severity-guidance: Workflow injection → critical. Floating action tags or wide default permissions → high. Lockfile drift without justification → high (runtime/peer dep) or medium (devDep only). Provenance opt-out → medium. +--- + +# CI / Release Security + +Focus: the trust boundary that ships our code. CI runs with privileged tokens; releases push artifacts under the org's identity. A bad workflow merge can leak secrets, run attacker code on a maintainer's box, or publish a poisoned package. This persona reviews diffs that touch that surface. + +## Trigger + +Fires when `` is true — i.e. any changed file matches: + +- `.github/workflows/**` +- `.github/actions/**` (composite or local actions) +- `.changeset/**` (changeset entries, changesets config) +- root `package.json` or any `packages/*/package.json` where a `scripts.*publish*` / `scripts.*release*` field is touched +- `pnpm-lock.yaml` +- `pnpm-workspace.yaml` +- `.npmrc` (any level) +- file content contains `changeset publish`, `npm publish`, `pnpm publish`, or `gh release create` + +## Prompt must include + +### Workflow injection (CRITICAL) + +- Any `${{ github.event.* }}`, `${{ github.head_ref }}`, or other attacker-controllable input interpolated directly into a `run:` block, `shell:` invocation, or third-party-action argument. The fix is always: assign to an env var first, then reference `$ENV_VAR` in the shell — never expand untrusted GitHub-context expressions in `run:` strings. +- `pull_request_target` triggers that also check out the PR head (`actions/checkout` with `ref: ${{ github.event.pull_request.head.sha }}` or similar). This pattern executes attacker code with write-scoped credentials. Flag unless the workflow demonstrably never runs the checked-out code (no install, no test, no script). +- `issue_comment` or `pull_request_review_comment` triggers that act on comment text without ACL gating (e.g. checking `github.event.comment.author_association == 'OWNER'`). + +### Action pinning (HIGH) + +- `uses:` lines that reference a floating ref — branch (`@main`, `@master`) or floating tag (`@v4`, `@v3.5`) — for any third-party action. Pin to a full commit SHA with the human-readable tag in a trailing comment: `uses: actions/checkout@<40-char-sha> # v4.1.7`. +- Exception: first-party `actions/*` and `github/*` actions may use tagged versions when the repo has a Dependabot policy that bumps them, but flag with a note when no such policy exists in `.github/dependabot.yml`. +- Newly added actions from unknown publishers — surface the publisher name and ask whether it was reviewed. + +### Workflow `permissions:` scopes (HIGH) + +- Missing top-level `permissions:` block in a new workflow — defaults to write-all on classic-permissions repos. Require an explicit `permissions:` block (job-level if scopes differ between jobs). +- Wide scopes where narrow ones would do: `contents: write` when only `contents: read` is needed; `id-token: write` outside of OIDC/provenance-publishing jobs; `pull-requests: write` outside of bot-comment jobs. +- `secrets: inherit` passed to reusable workflows — flag and request explicit secret listing. + +### Secret exposure (HIGH) + +- `secrets.*` interpolated into a `run:` block where it lands in logs (shell echo, `set -x`, error paths). Use `env:` to bind the secret, then reference `$VAR` inside the script so GitHub's redaction works. +- Secrets passed as arguments to third-party actions whose source is not pinned to a SHA. +- New secret names introduced without a matching reference in the repo's secrets-management doc (if `SECURITY.md` or similar documents them). + +### Publish-flow integrity (HIGH → CRITICAL) + +- `npm publish` / `pnpm publish` invocations: confirm `--provenance` is set (or that publishing happens via Changesets' provenance-aware path). Loss of provenance on an existing-provenance package is a downgrade. +- Authentication: confirm publishes use `NODE_AUTH_TOKEN` / `NPM_TOKEN` scoped to the org and not a personal access token; flag PATs. +- Tag scope: a workflow that previously only published to `next` now publishing to `latest` (or vice-versa) — surface as a release-flow change for human sign-off. +- New workflows that publish — require explicit dry-run path and a maintainer-approval gate (`environment:` with required reviewers) before the publish step. +- Provenance/SBOM toggles: any change that disables `--provenance` or removes a SLSA/SBOM emit step → **medium** finding minimum, **high** if the package is in the runtime/peer surface. + +### Changesets / release-bot wiring + +- `.changeset/config.json` changes — fixed-version, linked-package, baseBranch, or commit changes alter what gets shipped. Flag for human review on every change. +- New release workflows or release-bot actions — they typically hold elevated tokens; require pinned SHAs and explicit `permissions:`. +- Removed gating: if a previously-required check (lint, test, fork-suite) is dropped from the release workflow's `needs:`, flag as **high**. + +### Lockfile drift / dependency hygiene + +- `pnpm-lock.yaml` changes WITHOUT a corresponding `package.json` change — surface as a finding (could be a malicious lockfile-only attack, or legitimate transitive bump; ask for justification). +- New dependencies added to any `package.json`: + - **High** when the dep ends up in `dependencies` or `peerDependencies` of a published package (runtime surface). + - **Medium** when in `devDependencies` only. + - In both cases, flag deps with `postinstall` / `preinstall` / `install` scripts in their package metadata (read from the registry or the lockfile entry), unpinned semver ranges (`^` / `~`) on a runtime dep, or names that look like typosquats of known packages. +- Removed deps: confirm the corresponding code that used them is also removed (otherwise the build silently relies on a hoisted transitive). + +### `.npmrc` and `pnpm-workspace.yaml` + +- Registry changes (`registry=` or `@scope:registry=`) — flag any non-`registry.npmjs.org` URL for explicit human review. +- `always-auth=true` or `_authToken=` committed to the repo — **critical** (credential leak). +- New `auto-install-peers` / `strict-peer-dependencies` flips — flag as **medium**, surface impact on consumer install behavior. + +## Output expectations + +- Return findings in the same JSON shape as every other persona: `[{severity, file, line, description}]`. +- `description` must include both the *what* (concrete excerpt from the diff) and the *how to fix* (specific replacement, action SHA, env-var rewrite, etc.). Generic warnings without a fix are not actionable. +- If no CI/release concerns survive the diff scope, return `[]` — do NOT speculate about workflows that weren't changed. diff --git a/.agents/personas/code-quality.md b/.agents/personas/code-quality.md new file mode 100644 index 000000000..fe58f8198 --- /dev/null +++ b/.agents/personas/code-quality.md @@ -0,0 +1,31 @@ +--- +name: code-quality +kind: baseline +focus: TypeScript strict mode, type safety, early returns, `as` assertions, duplication, naming, code smells, magic numbers, overly complex functions, cross-file impact for SDK consumers, security primitives. +--- + +# Code Quality + +Focus: TypeScript strict mode, type safety, early returns, `as` assertions, duplication, naming, code smells, magic numbers, overly complex functions. + +Prompt must include: + +- Type safety issues (`any`, unsafe `as` assertions, missing generics) +- Error handling and edge cases +- Code smells (duplicated logic, overly complex functions, magic numbers) +- Early returns preferred over nested conditionals +- Naming conventions per the root `AGENTS.md` (and any per-package `AGENTS.md` for the file under review) +- Reference `AGENTS.md` (root, canonical), `MISSION.md`, the package's `AGENTS.md`, and `CONTRIBUTING.md` + +**Cross-file impact (critical for an SDK):** +- Changed exports from `packages//src/index.ts` — could break consumer code +- Function signature changes on public APIs (parameter add/remove/reorder/type-narrow) +- Renamed or removed exports +- API contract changes (return type, thrown error type, async-vs-sync) +- New deep imports into other packages (should go through `src/index.ts`) + +**Security:** +- Hardcoded secrets, tokens, private keys, RPC URLs with credentials +- Injection risks in any string-templated input (SQL-like queries, shell commands) +- Authentication bypass / authorization checks missing on entry points +- `eval`, `Function(...)` constructors, dynamic `import()` — flag any diff --git a/.agents/personas/documentation.md b/.agents/personas/documentation.md new file mode 100644 index 000000000..ba4a2d58e --- /dev/null +++ b/.agents/personas/documentation.md @@ -0,0 +1,21 @@ +--- +name: documentation +kind: baseline +focus: JSDoc/TSDoc on public APIs and types re-exported from `packages//src/index.ts`. +canonical-rules: docs/jsdoc-style.md +--- + +# Documentation Analyzer + +Focus: JSDoc/TSDoc on public APIs and types in `packages//src/index.ts` and the files it re-exports. + +**Canonical JSDoc rules: `docs/jsdoc-style.md`** (operationalizes AGENTS.md §6 and MISSION.md goal #3 — AI-legibility). Include the contents of `docs/jsdoc-style.md` (or a faithful summary) so reviewers flag deviations from the canonical shape. + +Prompt must include: + +- The `docs/jsdoc-style.md` checklist (what needs JSDoc, what does not, the required block order, `@param` / `@returns` / `@throws` / `@example` rules, error-message phrasing). +- New or modified public exports re-exported from `packages//src/index.ts` must have JSDoc that conforms to `docs/jsdoc-style.md`. +- Doc comments accurate vs. the implementation (no stale references to renamed args, removed return values, changed throw behavior). +- Public types use semantic names — flag generic `T`, `U`, `Foo` where domain names exist. +- README / package-level doc files updated when the public API changes shape. +- `@example` blocks compile and follow the runnable-recipe shape from the style guide. diff --git a/.agents/personas/module-api-architecture.md b/.agents/personas/module-api-architecture.md new file mode 100644 index 000000000..4a9d43ea0 --- /dev/null +++ b/.agents/personas/module-api-architecture.md @@ -0,0 +1,22 @@ +--- +name: module-api-architecture +kind: baseline +focus: Package boundaries, public surface, type/import discipline, NodeNext compatibility. +--- + +# Module & API Architecture + +Focus: package boundaries, public surface, type/import discipline, NodeNext compatibility. + +Prompt must include: + +- Public exports come from `packages//src/index.ts` only — no deep imports into other packages +- Relative imports include `.js` suffix (NodeNext) — e.g. `export * from "./market/index.js"` +- Prefer type-only imports where possible (`import type { Address } from "viem"`) +- Reuse SDK types for protocol values: `Address`, `MarketId`, `ChainId`, `BigIntish` +- `bigint` for onchain quantities and WAD-scaled rates (e.g. `92_0000000000000000n`) +- `as const` and `satisfies` for protocol lists and ABI literals (e.g. `BLUE_OPERATIONS as const`) +- Domain failures are typed `Error` subclasses with readonly inputs +- Edits to generated **inputs** (e.g. `graphql/*.gql`), not generated files (e.g. `src/api/sdk.ts`) +- No edits to build output under `lib/` +- Reference the root `AGENTS.md`, the package's `AGENTS.md` (and any nested `AGENTS.md`), and the package's own `package.json` `exports` field diff --git a/.agents/personas/silent-failure-hunter.md b/.agents/personas/silent-failure-hunter.md new file mode 100644 index 000000000..7dbe16b60 --- /dev/null +++ b/.agents/personas/silent-failure-hunter.md @@ -0,0 +1,19 @@ +--- +name: silent-failure-hunter +kind: baseline +focus: Swallowed errors, missing error boundaries, empty catch blocks, unhandled promise rejections, missing loading/error states, dead code paths. +--- + +# Silent Failure Hunter + +Focus: Swallowed errors, missing error boundaries, empty catch blocks, unhandled promise rejections, missing loading/error states, dead code paths. + +Prompt must include: + +- Empty or overly broad catch blocks that swallow errors +- Missing error boundaries around async components +- Unhandled promise rejections (missing `.catch()` or try/catch) +- Missing loading states for async operations +- Missing error states for failed data fetches +- Silently ignored return values from critical operations +- Dead code paths that can never execute diff --git a/.agents/personas/style-conventions.md b/.agents/personas/style-conventions.md new file mode 100644 index 000000000..462c27e04 --- /dev/null +++ b/.agents/personas/style-conventions.md @@ -0,0 +1,20 @@ +--- +name: style-conventions +kind: baseline +focus: Biome compliance, import discipline, monorepo conventions, changeset relevance. +--- + +# Style & Conventions Compliance + +Focus: Biome compliance, import discipline, monorepo conventions. + +Prompt must include: + +- Biome clean: 2-space indentation, organized imports, no unused imports/variables (`pnpm lint`) +- Type-only imports where possible (`import type { ... }`) +- Relative imports use `.js` suffix in source files (NodeNext) +- No edits to generated files (e.g. `src/api/sdk.ts`) — change generated **inputs** instead +- No edits to build output under `lib/` +- Reuse of SDK types (`Address`, `MarketId`, `ChainId`, `BigIntish`) over local re-declarations +- Reference the root `AGENTS.md`, the package's `AGENTS.md`, and `biome.json` +- Changeset relevance: verify `.changeset/*.md` files are present when the PR changes published package source in a semver-relevant way. Allow patch changesets for JSDoc-only changes to published package source. Flag unnecessary changesets for repo metadata, non-API documentation-only, fixture-only, generated-output-only, or tests-only diffs; flag missing changesets for behavior-affecting published package source changes. diff --git a/.agents/personas/test-coverage.md b/.agents/personas/test-coverage.md new file mode 100644 index 000000000..a7504b819 --- /dev/null +++ b/.agents/personas/test-coverage.md @@ -0,0 +1,17 @@ +--- +name: test-coverage +kind: baseline +focus: Missing or weak tests in `packages//test/` for changes in `packages//src/`. +--- + +# Test Coverage Analyzer + +Focus: missing or weak tests in `packages//test/` for changes in `packages//src/`. + +Prompt must include: + +- New public exports without a corresponding test file under `packages//test/` +- New code paths inside existing exports without test cases (branches, error paths, edge cases like zero/MAX_UINT256/negative bigints) +- Removed or modified public exports without tests updated +- Onchain code paths (any code calling `viem`/`wagmi` actions) — confirm there's at least one test that exercises the path against a fork or mock +- Snapshot or schema tests updated when generated outputs change diff --git a/.agents/personas/web3-security.md b/.agents/personas/web3-security.md new file mode 100644 index 000000000..7a4648803 --- /dev/null +++ b/.agents/personas/web3-security.md @@ -0,0 +1,22 @@ +--- +name: web3-security +kind: baseline +focus: Contract interactions, transaction parameters, wallet handling, permit flows, race conditions. +severity-guidance: This is CRITICAL review territory — findings default to critical or high. +--- + +# Web3 Security + +Focus: Contract interactions, transaction parameters, wallet handling, permit flows, race conditions. **This is CRITICAL review territory.** + +Prompt must include: + +- Contract interactions: verify correct contract addresses, function signatures, and arguments +- Transaction parameters: check gas estimates, value transfers, and calldata encoding +- Reactivity concerns: can state changes cause unintended transaction parameters? +- Wallet connection: proper account handling and chain verification +- Hook usage: correct usage of wagmi hooks (useContractRead, useContractWrite, etc.) +- Error handling: transaction failures, reverts, and user rejections +- Race conditions in async operations +- Missing transaction confirmations or proper waiting for receipts +- Permit/deadline handling (avoid stale block timestamps) diff --git a/AGENTS.md b/AGENTS.md index cfe45905a..f7d960b07 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,6 +8,8 @@ Every PR is measured against the rules below. A change that violates an architec > **Enforcement note.** Some rules below are enforced by tooling today (Biome formatter, fork harness in `@morpho-org/test`, Changesets generation). Most are **review-time conventions** that humans and reviewing agents apply: JSDoc on every export, layered-import bans, the §2 forbidden-patterns list (Biome's `noExplicitAny` is warn-level, `noParameterAssign` is disabled, and there's no rule banning `as unknown as` / `@ts-ignore` / async-in-actions / framework imports / mocked viem clients on RPC paths), changeset-gates-CI, full coverage thresholds. Where a rule isn't backed by an automated check, treat it as binding regardless — wiring CI gates is tracked separately. +> **Review personas.** The review-time conventions above are implemented by the `/pr-review-{ci,gh,local}` slash commands, which fan out to specialized review personas at [`.agents/personas/`](./.agents/personas/). Baseline personas fire on every review: `code-quality`, `module-api-architecture`, `web3-security`, `silent-failure-hunter`, `style-conventions`, `documentation`, `test-coverage`. Conditional personas fire when their trigger flag is true: `ci-release-security` (when the diff touches `.github/workflows/**`, `.changeset/**`, `pnpm-lock.yaml`, `.npmrc`, or publish-flow scripts). Adding a new convention to this file usually means adding a matching bullet to the relevant persona — keep the two in sync. + --- ## 1. Architecture