Files
motr-enclave/AGENTS.md

4.1 KiB

Agent Guidelines for Motr Enclave

This document provides guidelines for AI coding agents working in this repository.

Project Overview

Motr Enclave is an Extism WebAssembly plugin written in Go, compiled with Go 1.25+ for the wasip1 target. It provides encrypted key storage for the Nebula wallet with an embedded SQLite database.

Build Commands

# Build WASM plugin (primary build command)
make build

# Build with debug symbols
make build-debug

# Build optimized (requires wasm-opt)
make build-opt

# Generate SQLC database code
make generate

# Full rebuild
make clean && make generate && make build

Test Commands

# Run all tests
make test

# Run tests with coverage
make test-cover

# Run a single test
go test -v -run TestFunctionName ./...

# Run tests in a specific package
go test -v ./db/...

# Test the compiled plugin with Extism CLI
make test-plugin

Lint and Format

# Run all linters
make lint

# Format code
make fmt

# Run go vet
make vet

# Run all checks (fmt, vet, lint, test)
make verify

Code Style Guidelines

Imports

Order imports in three groups separated by blank lines:

  1. Standard library
  2. External dependencies
  3. Internal packages
import (
    "encoding/json"
    "errors"
    "fmt"

    "github.com/extism/go-pdk"

    "enclave/db"
)

Naming Conventions

Element Convention Example
Exported types PascalCase GenerateInput, QueryOutput
Unexported types PascalCase FilterParams (internal use ok)
Struct fields PascalCase CredentialID, ChainID
JSON tags snake_case json:"credential_id"
Functions camelCase for private, PascalCase for exported parseFilter, Generate
Constants PascalCase or ALL_CAPS MaxRetries
Variables camelCase credentialBytes, didDoc

Type Definitions

Define input/output types for each exported function:

type GenerateInput struct {
    Credential string `json:"credential"`
}

type GenerateOutput struct {
    DID      string `json:"did"`
    Database []byte `json:"database"`
}

Extism Plugin Functions

Exported functions must:

  1. Use //go:wasmexport directive
  2. Return int32 (0 = success, 1 = error)
  3. Use pdk.InputJSON() for input parsing
  4. Use pdk.OutputJSON() for output
  5. Use pdk.SetError() for error reporting
  6. Log with pdk.Log()
//go:wasmexport functionName
func functionName() int32 {
    pdk.Log(pdk.LogInfo, "functionName: starting")

    var input InputType
    if err := pdk.InputJSON(&input); err != nil {
        pdk.SetError(fmt.Errorf("functionName: failed to parse input: %w", err))
        return 1
    }

    // ... implementation ...

    if err := pdk.OutputJSON(output); err != nil {
        pdk.SetError(fmt.Errorf("functionName: failed to output: %w", err))
        return 1
    }
    return 0
}

Error Handling

  1. Wrap errors with context using fmt.Errorf("context: %w", err)
  2. Prefix error messages with function name
  3. Return early on errors
  4. Use errors.New() for static errors
if err != nil {
    pdk.SetError(fmt.Errorf("generate: failed to initialize: %w", err))
    return 1
}

SQL Queries (SQLC)

  • Schema in db/schema.sql
  • Queries in db/query.sql
  • Use SQLC annotations: -- name: QueryName :one|:many|:exec
  • JSON columns use json.RawMessage type override

Comments

  • Only add comments for complex logic, security implications, or TODOs
  • Avoid obvious comments
  • Use // TODO: for planned implementations

File Structure

motr-enclave/
├── main.go           # Plugin entry point, exported functions
├── db/
│   ├── schema.sql    # Database schema
│   ├── query.sql     # SQLC query definitions
│   └── *.go          # Generated SQLC code
├── sqlc.yaml         # SQLC configuration
├── Makefile          # Build commands
└── go.mod            # Go module

Dependencies

Install with make deps:

  • sqlc - Database code generation
  • golangci-lint - Linting
  • gofumpt - Formatting
  • Extism CLI - Plugin testing