AGENTS.mdis 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.
- Codex:
AGENTS.md(this file) - Cursor:
.cursor/rules/documentation.mdc,.cursor/BUGBOT.md, thenAGENTS.md - Claude Code:
CLAUDE.md, thenAGENTS.md - GitHub Copilot:
.github/copilot-instructions.md, thenAGENTS.md
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
ghCLI with access to read PR comments, write PR comments, resolve review threads, and push the current branch.
- 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/)
- contracts/AGENTS.md — Solidity contracts, deployment artifacts
- e2e/AGENTS.md — E2E tests, ABI generation
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.mdat root vs package-level*/AGENTS.md)
Only propose rules that are repository-specific and repeatable.
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.
| 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 |
pnpm installThis triggers husky setup via the prepare script. Only pnpm is allowed (enforced by preinstall).
| Package | Command |
|---|---|
| Full local stack | make start-env |
| L1 + L2 with tracing | make start-env-with-tracing-v2 |
# 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| 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 |
| 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.
- TypeScript packages: typecheck is part of build (
tsc)
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.
| 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 |
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.
Prefer LSP tools over Grep/Glob/Read for code navigation:
goToDefinition/goToImplementation— jump to source instead of greppingfindReferences— find all call sites before renaming or changing a signatureworkspaceSymbol— locate where a type or function is defineddocumentSymbol— list all symbols in the current filehover— get type info without opening the fileincomingCalls/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.
- 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
.gitattributesand.editorconfig) - TypeScript: strict mode, ES2022 target, nodenext module resolution
- 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.yamlcatalog section - Shared ESLint config:
@lfdt-lineth/eslint-configwith exports for default,./nextjs, and./node
| 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 |
- TypeScript: ESLint import ordering enforced via
eslint-plugin-import - Solidity: Named imports only (
import { X } from "./X.sol") - Kotlin: Star imports disabled (see
.editorconfig)
| 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, andtracer linea-shared-utilsenforces strict coverage thresholds (branches: 85.71%, functions: 100%, lines: 95.23%)- Protocol E2E tests require a running local stack (
make start-env)
- 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
- 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
- Tests pass locally (
pnpm run testor 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:
gofmtandgolangci-lint runpass - 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.templatefiles - Relevant issue linked in PR description
- Load secrets from environment variables or secure vaults exclusively
.envfiles are in.gitignore; only.env.template/.env.examplefiles 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 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.mdfor Solidity-specific security rules
- pnpm catalog: Shared dependency versions in
pnpm-workspace.yaml - Gradle version catalog:
gradle/libs.versions.toml - Security overrides: Explicit in
pnpm-workspace.yamlfor known CVEs - Dependabot: Configured for GitHub Actions dependencies (weekly, Monday 03:00 UTC)
- Engine strict:
engine-strict=truein.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.
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
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
- Read existing code in the affected area
- Check for existing tests, conventions, and patterns in that package
- Prefer built-in language, framework, library, and repository helpers over hand-rolled replacements when equivalent functionality already exists
- Extend or compose existing helpers before introducing a new utility when that keeps the implementation smaller and clearer
- Plan the minimal change needed
- 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.
- Implement with tests
- Run the package-specific lint and test commands
- Verify no secrets or credentials are exposed
- 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
| 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 |
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)
- Platform: GitHub Actions
- Main workflow:
.github/workflows/main.yml— triggers on PR and push tomain - Path filtering:
dorny/paths-filterdetects 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 (
tracerflag) - 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
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/*
| Dependency | Documentation | Notes |
|---|---|---|
| Hyperledger Besu | besu/docs | Besu APIs, plugin interfaces, and internals — prefer this over grepping compiled JARs or decompressing artifacts |
- README — Repository overview
- Get Started — Quick start guide
- Local Development Guide — Coordinator local setup
- Contributing — Contribution guidelines and release process
- Security Policy — Vulnerability reporting
- Code of Conduct — Community guidelines
- Contract Style Guide — Solidity conventions
- Contract Deployment — Deployment parameters