Skip to content

Latest commit

 

History

History
183 lines (138 loc) · 9.18 KB

File metadata and controls

183 lines (138 loc) · 9.18 KB

AGENTS.md — AI Agent Guide for the Gno Repository

Primary entry point for any AI agent working in this codebase. Also read CONTRIBUTING.md for general contribution guidelines.


Project Overview

Gno (Gnolang) is a deterministic, interpreted variant of Go for writing smart contracts. gno.land is the L1 blockchain that runs Gno code.

Pillar Directory What it does
GnoVM gnovm/ Interpreter/VM, parser, type-checker
gno.land gno.land/ Blockchain node, ABCI app, SDK, CLI tools
Tendermint2 tm2/ Consensus, p2p, mempool, crypto, RPC

Other directories: examples/ (sample realms/packages), contribs/ (tools: gnodev, gnofaucet, etc.), misc/, docs/, .github/.


.gno Files Are NOT Go

  • .gno looks like Go but runs in a deterministic VM.
  • No goroutines, channels, unsafe, net, os.
  • Realms (r/) are stateful (on-chain state).
  • Packages (p/) are stateless libraries.
  • Import paths: gno.land/p/... or gno.land/r/...never github.com/....
  • Module config: gnomod.toml (not go.mod).
  • cross(rlm) form for cross-realm calls.
  • realm type for realm-aware functions.

Build & Test

make install                    # Install gnokey, gno, gnodev
make test                       # Run all tests (slow)
make lint                       # golangci-lint
make fmt                        # Format all code
Gno tests Go tests
gno test ./path/... go test ./...
Test files: _test.gno Test files: _test.go
Filetests: _filetest.gno Integration: .txtar in gno.land/pkg/integration/testdata/
VM file tests: gnovm/tests/files/ with // Output: Standard Go test runner

Verification Rules

  • After changing gas constants or allocation/GC logic, always run these before declaring done:
    • go test ./gno.land/pkg/sdk/vm/ -run Gas
    • go test ./gno.land/pkg/integration/ -run TestTestdata
    • go test ./gnovm/pkg/gnolang/ -run Files -test.short
  • Always run /simplify before presenting completed work on non-trivial changes.
  • When comparing gas numbers or performance metrics before vs after, always verify the test logic has not changed, including loop counts and input sizes. Show reasoning, not just numbers.
  • Never claim a percentage improvement without confirming the test is doing the same work in both cases.

Conventions

Gno (.gno)

  • Format: gno fmt.
  • Import paths: gno.land/{p,r}/... only.
  • No OS/network access.
  • Before writing Gno code, read the relevant docs in docs/resources/:
    • gno-interrealm.md — cross-realm calls, cross(rlm)/realm semantics
    • effective-gno.md — idiomatic Gno patterns
    • go-gno-compatibility.md — what works and what doesn't vs Go
    • gno-testing.md — testing patterns for .gno files
    • gno-packages.md — package structure and conventions

Go (.go)

  • Format: gofmt/goimports.
  • Lint: golangci-lint (.github/golangci.yml).

Universal

  • Commits: conventional (feat:, fix:, docs:, chore:, test:, refactor:) with optional scope (feat(gnovm):).
  • Branches: kebab-case (fix-vm-params), always feature branches.
  • If posting comments or reviews under your owner's GitHub account fully autonomously (no human reviewing the output before it is posted), disclose that you are an AI agent (e.g., prefix with [bot] or add a "generated by" note) so humans can distinguish agent activity from the account owner. Human-assisted contributions that the account owner reviews and approves before posting do not need this disclosure.
  • Don't credit the agent as a commit author (Co-Authored-By, Assisted-By, "Generated by"); the human author owns the commit. Note AI usage in the PR description if relevant.
  • When writing PR descriptions, grep for all new/modified files in the diff (git diff --stat) and categorize them. Do not omit major new files like benchmarks, tooling, or calibration scripts.
  • List all categories of work in PR descriptions, including features, bug fixes, tooling, and tests, not just the headline feature.
  • Keep PRs up to date with master — merge regularly and resolve conflicts promptly.
  • When merging master into your branch, review incoming changes carefully. If CONTRIBUTING.md or AGENTS.md was updated, re-read and follow the latest rules.
  • Be respectful and helpful in PR comments and reviews — optimize for the reviewer's time, especially human maintainers.
  • See CONTRIBUTING.md.

Gno Security Semantics

  • Before writing or reviewing any caller-authentication, access-control, or cross-realm code in Gno (/r/, /p/, /e/ packages), read docs/resources/gno-interrealm.md. Do not pattern-match from Solidity msg.sender or other-language intuition.
  • For the complete AI-focused checklist (10 cases), read docs/resources/gno-ai-contract-review.md before reviewing any realm.
  • runtime.PreviousRealm() only shifts on explicit cross-calls (fn(cross, ...)) into crossing functions (func fn(cur realm, ...){...}). A PreviousRealm().PkgPath() == "..." check inside a non-crossing function does not identify the immediate caller and is a security bug.
  • In crossing functions (func F(cur realm, ...)), always use cur.IsCurrent() before calling cur.Previous(). Never use chain/runtime/unsafe.PreviousRealm() in a crossing function — it bypasses the frame verification that cur.IsCurrent() provides. Any import of chain/runtime/unsafe alongside cur realm parameters is a red flag.
  • When editing a realm that accepts payment via banker.OriginSend(), the caller guard must be cur.Previous().IsUserCall(), not IsUser(). IsUser() accepts maketx run ephemeral realms, which can consume the origin-send envelope before calling your function and bypass the payment check. See docs/resources/effective-gno.md § Verifying inbound Coin payments.
  • When you see an existing realm using IsUser() plus banker.OriginSend(), flag it and cross-check nearby OriginSend usage.
  • Never return a pointer to a /p/-type instance stored in realm state if that type has any exported mutation method (e.g. avl.Tree.Set, avl.Tree.Remove). Readonly taint does not block method dispatch — borrow rule #2 fires and the write commits under your realm's authority. Return values or narrow read-only views instead.
  • Render(path string) receives attacker-controlled input. Never write path segments, user-supplied keys, or free-form string values directly into markdown output. Use sanitize.InlineText from gno.land/p/nt/markdown/sanitize/v0 for inline content.

Architecture Decision Records (ADRs)

Every non-trivial AI-assisted PR must include an ADR. This documents what the AI understood so reviewers can verify assumptions and future contributors can build on it.

Scope Directory
GnoVM gnovm/adr/
gno.land gno.land/adr/
Tendermint2 tm2/adr/

Naming: pr<number>_<description>.md. Use prxxxx_ if PR number unknown.

Include: context, decision, alternatives considered, consequences. See gnovm/adr/ for examples. Match detail to complexity.

Skip ADRs for: trivial bug fixes, formatting, simple tests, docs-only changes.


Don'ts

  • git push --force — never force push unless explicitly asked.
  • --no-verify — never skip hooks.
  • go generate — slow, large diffs. Only if explicitly asked.
  • Modify gno.land/genesis/ — only if that's the task.
  • Goroutines/OS calls in .gno — never works.
  • Break gno.land/p/demo/ backwards-compat — needs discussion.
  • AI-assisted PRs without an ADR.

Navigation

What Where
Understand a realm Read its main .gno file
VM internals gnovm/pkg/gnolang/machine.go, gnovm/pkg/gnolang/preprocess.go
Node/keeper gno.land/pkg/sdk/vm/keeper.go
Client/RPC gno.land/pkg/gnoclient/
Example patterns examples/gno.land/p/nt/ownable/
Past decisions gnovm/adr/, gno.land/adr/ and tm2/adr/

Glossary

  • Realm — stateful smart contract (.gno, under r/)
  • Package — stateless library (under p/)
  • GnoVM — the interpreter
  • gno.land — the blockchain
  • Gnolang — the language
  • ADR — architecture decision record
  • ABCI — app-to-consensus interface
  • GovDAO — governance DAO
  • gnokey — key/tx CLI
  • gnoland — node binary
  • gnodev — local dev with hot reload

Improving This Document

This file should stay concise, correct, and useful. Both humans and agents should help maintain it.

Humans: if you spot something wrong or missing, fix it directly — small PRs welcome. If an agent got confused by something, add a clarification here so the next one doesn't.

Agents: if you hit something misleading or missing in this doc during your work, flag it to the human and suggest a concrete edit. Include the fix in your PR when practical — future agents will benefit. If your human corrects you on something that this doc could have prevented, propose adding it.

The goal is a living document that gets sharper with each use.