Skip to content

Latest commit

 

History

History
433 lines (332 loc) · 19.7 KB

File metadata and controls

433 lines (332 loc) · 19.7 KB

AGENTS.md

Documentation Precedence

  • AGENTS.md is the canonical source for repository-wide agent instructions.
  • Tool-specific files should stay concise and link back to AGENTS.md.
  • If instructions conflict, follow AGENTS.md.

Agent Entry Points

  • Codex: AGENTS.md (this file)
  • Cursor: .cursor/rules/documentation.mdc, .cursor/BUGBOT.md, then AGENTS.md
  • Claude Code: CLAUDE.md, then AGENTS.md
  • GitHub Copilot: .github/copilot-instructions.md, then AGENTS.md

Local Agent Workflows

  • squash-bugbot: canonical skill at .agents/skills/squash-bugbot/SKILL.md.
  • Use /squash-bugbot <PR_NUMBER> locally in Codex, Cursor, or Claude Code to triage unresolved bot PR comments.
  • Claude Code exposes the same workflow through .claude/commands/squash-bugbot.md, a symlink to the canonical skill.
  • Requires an authenticated gh CLI with access to read PR comments, write PR comments, resolve review threads, and push the current branch.

Discoverability Index

  • Repository overview: README.md
  • Contribution process: CONTRIBUTING.md, docs/contribute.md
  • Local setup: docs/get-started.md, docs/local-development-guide.md
  • Architecture: docs/architecture-description.md
  • Engineering guidelines: docs/development-guidelines.md
  • Security and audits: docs/security.md, docs/audits.md
  • Package-specific agent rules: */AGENTS.md (contracts/, coordinator/, prover/, tracer/, ts-libs/sdk/, linea-besu/plugins/, transaction-exclusion-api/, e2e/)

Project Guidelines

Continuous Improvement

When a task requires a significant course correction (e.g., wrong architecture choice, misunderstood repository pattern, missed convention), propose an update to the relevant AGENTS.md.

For each proposal, include:

  • What failed or was ambiguous
  • Why it caused rework or risk
  • The concrete rule to add or modify
  • The correct scope (AGENTS.md at root vs package-level */AGENTS.md)

Only propose rules that are repository-specific and repeatable.

Repository

Lineth zkEVM monorepo — the principal repository for Linea, a Layer 2 zero-knowledge rollup scaling Ethereum. Contains smart contracts, ZK prover, coordinator, postman (bridge message executor), SDKs, and supporting tooling. Licensed under Apache-2.0 and MIT.

How to Run

Prerequisites

Tool Version Notes
Node.js >= 24.18.0 See .nvmrc
pnpm >= 11.9.0 Enforced via preinstall
JDK 25 Coordinator, Besu plugins, transaction-exclusion-api — enforced by Gradle; JDK 25+ required
Gradle 9.4+ use ./gradlew
Go 1.25.7 Prover
Docker 24+ Local stack, CI
Docker Compose 2.19+ Multi-service orchestration
Make 3.81+ Environment management
Foundry stable Solidity testing and docgen

Install

pnpm install

This triggers husky setup via the prepare script. Only pnpm is allowed (enforced by preinstall).

Dev

Package Command
Full local stack make start-env
L1 + L2 with tracing make start-env-with-tracing-v2

Build

# All pnpm packages
pnpm run build

# Coordinator (Kotlin)
./gradlew :coordinator:app:build

# Prover (Go)
cd prover && make build

# Contracts (Solidity)
pnpm -F contracts run build

Test

Scope Command
All pnpm packages pnpm run test
Contracts (Hardhat) pnpm -F contracts run test
Contracts (coverage) pnpm -F contracts run coverage
SDK core pnpm -F @lfdt-lineth/sdk-core run test
SDK ethers pnpm -F @lfdt-lineth/sdk run test
SDK viem pnpm -F @lfdt-lineth/sdk-viem run test
Postman pnpm -F @lfdt-lineth/postman run test
E2E (requires local stack) pnpm -F e2e run test:local
Coordinator (Kotlin) ./gradlew :coordinator:app:test
Prover (Go) cd prover && go test ./... -tags nocorset,fuzzlight -timeout 30m
Native libs pnpm -F @lfdt-lineth/native-libs run test
Shared utils pnpm -F @lfdt-lineth/shared-utils run test
Automation service pnpm -F @lfdt-lineth/native-yield-automation-service run test
Lido governance monitor pnpm -F @lfdt-lineth/lido-governance-monitor run test

Lint and Format

Scope Check Fix
All pnpm packages pnpm run lint pnpm run lint:fix
Contracts — Solidity pnpm -F contracts run lint:sol pnpm -F contracts run lint:sol:fix
Contracts — TypeScript pnpm -F contracts run lint:ts pnpm -F contracts run lint:ts:fix
Contracts — Prettier pnpm -F contracts run prettier:sol pnpm -F contracts run prettier:sol:fix
JVM — Spotless ./gradlew spotlessCheck ./gradlew spotlessApply
Prover (Go) cd prover && gofmt -l . && golangci-lint run cd prover && gofmt -w .

Prettier config: prettier.config.mjs. Formatting is integrated into lint:fix.

Typecheck

  • TypeScript packages: typecheck is part of build (tsc)

Code Intelligence (LSP)

LSP provides precise navigation (go-to-definition, find-references, diagnostics) and is far more reliable than text search. Use it as the primary navigation strategy when LSP tools are available.

Setup

Step 1 — install language server binaries

Language macOS Linux/Windows
TypeScript / JS npm install -g typescript-language-server typescript same
Go go install golang.org/x/tools/gopls@latest (ensure $GOPATH/bin is in $PATH) same
Java brew install jdtls download from eclipse-jdtls releases, symlink bin/jdtls into $PATH
Kotlin brew install JetBrains/utils/kotlin-lsp download from kotlin-lsp releases, add bin/ to $PATH

Step 2 — install plugins in Claude Code

Run /plugins and install typescript-lsp, gopls-lsp, jdtls-lsp, and kotlin-lsp from the claude-plugins-official marketplace. The project's .claude/settings.json already enables them and sets ENABLE_LSP_TOOL=1, so no changes to your personal settings are needed.

Restart Claude Code after installing.

Usage

Prefer LSP tools over Grep/Glob/Read for code navigation:

  • goToDefinition / goToImplementation — jump to source instead of grepping
  • findReferences — find all call sites before renaming or changing a signature
  • workspaceSymbol — locate where a type or function is defined
  • documentSymbol — list all symbols in the current file
  • hover — get type info without opening the file
  • incomingCalls / outgoingCalls — trace call hierarchy

Use Grep/Glob only for text/pattern searches (comments, string literals, config values) where LSP doesn't apply.

Important: Every LSP operation requires a filePath pointing to a file, never a directory. The file routes the request to the correct language server — pass any relevant file in the project if you don't have a specific one in mind.

After writing or editing code, check LSP diagnostics and fix any type errors or missing imports before moving on.

Code Conventions

Style

  • Formatter: Prettier 3.8.4 — prettier.config.mjs
  • Linter (TS/JS): ESLint 9.39.4 flat config — ts-libs/eslint-config/
  • Linter (Solidity): Solhint 6.2.1 + Prettier plugin
  • Linter (Kotlin/Java): Spotless with ktlint + Google Java Format
  • Linter (Go): gofmt + golangci-lint
  • Line length: 120 characters
  • Indentation: 2 spaces (4 for Go tabs)
  • Trailing commas: always (TS/JS)
  • Semicolons: always (TS/JS)
  • Quotes: double (TS/JS)
  • Line endings: LF (enforced via .gitattributes and .editorconfig)
  • TypeScript: strict mode, ES2022 target, nodenext module resolution

Structure

  • Monorepo tool: pnpm workspaces (pnpm-workspace.yaml)
  • Dual build systems: pnpm for TypeScript/JavaScript, Gradle for Kotlin/Java, Make+Go for prover
  • Dependency catalog: Shared versions in pnpm-workspace.yaml catalog section
  • Shared ESLint config: @lfdt-lineth/eslint-config with exports for default, ./nextjs, and ./node

Naming

Context Convention Example
TS/JS files kebab-case message-service.ts
React components PascalCase ResultsPanel.tsx
Solidity files PascalCase LineaRollup.sol
Solidity interfaces I prefix + PascalCase ILineaRollup.sol
Kotlin files PascalCase CoordinatorApp.kt
Go files snake_case blob_compressor.go
Branch names type/issue#-short-description feature/123-add-login-button
Commit messages type(issue#): description fix(456): corrected login error

Imports

  • TypeScript: ESLint import ordering enforced via eslint-plugin-import
  • Solidity: Named imports only (import { X } from "./X.sol")
  • Kotlin: Star imports disabled (see .editorconfig)

Testing Guidelines

Area Framework Notes
Contracts (Hardhat) Hardhat + ethers.js pnpm -F contracts run test
Contracts (Foundry) Forge test/foundry/*
TypeScript packages Jest 30.4.2 + ts-jest pnpm -F <pkg> run test
Coordinator JUnit 5 + Mockito + WireMock ./gradlew :coordinator:app:test
Prover Go test go test ./... -tags nocorset,fuzzlight
E2E (protocol) Jest pnpm -F e2e run test:local
  • Coverage: Codecov with flags for hardhat, kotlin, postman, sdk-viem, sdk-core, sdk-ethers, linea-shared-utils, linea-native-libs, native-yield-automation-service, lido-governance-monitor, and tracer
  • linea-shared-utils enforces strict coverage thresholds (branches: 85.71%, functions: 100%, lines: 95.23%)
  • Protocol E2E tests require a running local stack (make start-env)

Contribution Workflow

Branches and Commits

  • Strategy: Trunk-based development on main
  • Branch naming: type/issue#-short-description (e.g., feature/123-add-login-button, bugfix/456-fix-login-error)
  • Commit format: type(issue#): short description (e.g., fix(456): corrected login error)
  • Base branch: main

Pull Requests

  • PR template: .github/pull_request_template.md
  • CI must pass: tests, linting, security analysis, coverage
  • PRs are reviewed by maintainers
  • External PRs follow the standard deployment flow
  • CODEOWNERS: /contracts/ requires review from @Consensys/linea-contract-team

Checklist Before PR

  • Tests pass locally (pnpm run test or package-specific test command)
  • Linting passes (pnpm run lint)
  • Solidity: NatSpec complete for all public/external items
  • Solidity: Named imports used, linting passes (pnpm -F contracts run lint:fix)
  • Kotlin/Java: Spotless passes (./gradlew spotlessCheck)
  • Go: gofmt and golangci-lint run pass
  • No secrets, credentials, or real private keys in code
  • Breaking API changes: new versioned method/asset created (see versioning rules)
  • Environment variable changes reflected in .env.example / .env.template files
  • Relevant issue linked in PR description

Safety and Quality

Secrets

  • Load secrets from environment variables or secure vaults exclusively
  • .env files are in .gitignore; only .env.template / .env.example files committed with placeholders
  • Never log secrets, API keys, private keys, or credentials (see .cursor/rules/security-logging-guidelines/)
  • Test fixtures use obviously fake credentials (e.g., Hardhat default keys for local-only dev)

Security

  • Security contact: security-report@linea.build
  • Bug bounty: Immunefi program
  • CodeQL runs on all PRs (Go, Java-Kotlin, JavaScript-TypeScript, Python, GitHub Actions)
  • Weekly Dockerfile security scan via KICS
  • Dependency security overrides managed in pnpm-workspace.yaml (pnpm.overrides)
  • Smart contracts: See contracts/AGENTS.md for Solidity-specific security rules

Dependencies

  • pnpm catalog: Shared dependency versions in pnpm-workspace.yaml
  • Gradle version catalog: gradle/libs.versions.toml
  • Security overrides: Explicit in pnpm-workspace.yaml for known CVEs
  • Dependabot: Configured for GitHub Actions dependencies (weekly, Monday 03:00 UTC)
  • Engine strict: engine-strict=true in .npmrc

Additions to pnpm.onlyBuiltDependencies require a security review of the package's install script, including its network, filesystem, and process execution surface, publisher reputation, and recent npm publish history.

Irreversible Operations

These require human approval and follow the release process:

  • Smart contract deployments to testnet/mainnet
  • Database migrations on shared environments
  • Docker image pushes to production registries
  • Maven Central releases (maven-release.yml)
  • Linea Besu package releases
  • Any changes to production configuration

Agent Rules

When to Ask vs Assume

Ask when:

  • The change affects a public API consumed by another component or external partner
  • The change touches smart contract storage layout or upgrade logic
  • The change modifies CI/CD workflows or deployment pipelines
  • The change introduces a new dependency
  • The scope is ambiguous or crosses multiple packages

Assume when:

  • Adding tests for existing code
  • Fixing a clear bug with an obvious solution
  • Updating documentation to match existing behavior
  • Formatting or linting fixes

Proposing Changes

  1. Read existing code in the affected area
  2. Check for existing tests, conventions, and patterns in that package
  3. Prefer built-in language, framework, library, and repository helpers over hand-rolled replacements when equivalent functionality already exists
  4. Extend or compose existing helpers before introducing a new utility when that keeps the implementation smaller and clearer
  5. Plan the minimal change needed
  6. Plan review: Before starting implementation, review the plan using a separate agent with isolated context — give it only the original user request and the plan document, not the planning conversation or exploration history. This ensures the reviewer cannot inherit reasoning errors made during planning.
  7. Implement with tests
  8. Run the package-specific lint and test commands
  9. Verify no secrets or credentials are exposed

Limiting Change Surface

  • Change only what is directly requested
  • Do not refactor surrounding code unless asked
  • Do not add features beyond the scope
  • Do not modify files outside the affected package unless necessary for the change
  • Preserve existing code style in the file being edited

Repository Map

Packages

Name Type Stack Purpose
contracts Smart contracts Solidity 0.8.33, Hardhat, Foundry Core protocol contracts (rollup, messaging, bridge, tokens)
coordinator Backend service Kotlin 2.4.0, Gradle, Vertx Orchestrates proof submission, blob submission, finalization
prover Backend service Go 1.25.7 ZK proof generation (gnark, gnark-crypto)
postman Backend service TypeScript, Express, TypeORM Bridge message execution service
ts-libs/sdk/sdk-core Library TypeScript, tsup Core SDK utilities and types
ts-libs/sdk/sdk-ethers Library TypeScript, ethers.js 6 SDK for ethers.js integration
ts-libs/sdk/sdk-viem Library TypeScript, tsup, Viem SDK for Viem integration
e2e Tests TypeScript, Jest Protocol-level end-to-end tests
operations/cli CLI tool TypeScript, oclif Operations management CLI
ts-libs/eslint-config Config ESLint 9 flat config Shared ESLint configuration
ts-libs/linea-native-libs Library TypeScript, Koffi (FFI) Native library bindings
ts-libs/linea-shared-utils Library TypeScript, Express, Viem Shared utilities (server, metrics, logging)
operations/native-yield/automation-service Backend service TypeScript, Apollo Automated native yield operations
operations/native-yield/lido-governance-monitor Backend service TypeScript, Prisma Lido governance proposal monitoring
linea-besu/plugins Plugins Kotlin, Gradle Besu blockchain client plugins (sequencer, state recovery)
jvm-libs Libraries Kotlin, Gradle Shared JVM libraries (JSON-RPC, HTTP, persistence, metrics)
transaction-exclusion-api Backend service Kotlin, Gradle, Vertx Transaction exclusion tracking API
tracer Backend service Java/Go Corset, Gradle EVM trace generation and arithmetization

Key Directories

contracts/               Solidity smart contracts (Hardhat + Foundry)
coordinator/             Kotlin coordinator service
prover/                  Go ZK prover
postman/                 TypeScript bridge message executor
ts-libs/sdk/             TypeScript SDKs (core, ethers, viem)
e2e/                     Protocol E2E tests
operations/              Operations tools
operations/cli/          Operations CLI tool
ts-libs/                 Shared TypeScript libraries
operations/native-yield/ Native yield services
linea-besu/plugins/      Besu client plugins
jvm-libs/                Shared Kotlin/Java libraries
transaction-exclusion-api/ Transaction exclusion API
tracer/                  EVM tracer
docker/config/           Service configuration files (TOML, JSON, XML)
docker/                  Docker Compose files for local stack
docs/                    Project documentation
.github/workflows/       CI/CD workflows
.github/actions/         Custom GitHub Actions
.cursor/rules/           Cursor IDE rules
.agents/skills/          Agent skills (smart contract, dependency maintenance, local PR workflows)

CI/CD

  • Platform: GitHub Actions
  • Main workflow: .github/workflows/main.yml — triggers on PR and push to main
  • Path filtering: dorny/paths-filter detects which components changed
  • Pipeline: Filter changed paths -> Run component tests -> Build Docker images -> E2E tests -> Publish
  • Coverage: Codecov with Jacoco (JVM), Hardhat (Solidity), Jest LCOV (TS packages), and tracer Jacoco XML (tracer flag)
  • Security: CodeQL analysis, KICS Dockerfile scanning (weekly)
  • Runners: Custom scale-set runners (small, med, large, xl) on Ubuntu 22.04
  • Concurrency: Cancel in-progress runs on PRs; serial on main
  • Notifications: Slack alerts on workflow failures; external contribution notifications

Cross-Package Dependencies

postman -> @lfdt-lineth/sdk-viem -> @lfdt-lineth/sdk-core
postman -> @lfdt-lineth/native-libs, @lfdt-lineth/shared-utils
e2e -> @lfdt-lineth/shared-utils
operations/cli -> (standalone, uses ethers + viem)
operations/native-yield/* -> @lfdt-lineth/shared-utils
coordinator -> jvm-libs/*
transaction-exclusion-api -> jvm-libs/*
linea-besu/plugins -> jvm-libs/*

External Docs

Dependency Documentation Notes
Hyperledger Besu besu/docs Besu APIs, plugin interfaces, and internals — prefer this over grepping compiled JARs or decompressing artifacts

Internal Docs