iota-sdk
AGENTS.md471 starsChanged 30 days agoApache-2.0View on GitHub
Before adding a consumer workaround for shared SDK behavior, trace the SDK API, available extension points, and affected consumers. Fix a reusable capability or invariant in the SDK; when a consumer exposed the defect, validate the fix in that consumer's preview workflow. Keep product-specific policy and workflow in the consumer. Decide from the actual ownership boundary, not from which repository first exposed the defect. Each module follows a strict Domain-Driven Design (DDD) pattern with clear layer separation:
We split this AGENTS.md into the rules it gives an agent
45 rules. About 0 are common, 8 are distinctive, and 37 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
37
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 4
DO NOT COMMENT EXECESSIVELY.
- Distinctive: line 9
Prefer interfaces over concrete structs at boundaries
- Distinctive: line 11
Keep domain and services decoupled from infrastructure details
- Distinctive: line 15
Before adding a consumer workaround for shared SDK behavior, trace the SDK API, available extension points, and affected consumers.
- Very specific: line 73
Create domain entity in modules/{module}/domain/aggregates/{entity_name}/
- Very specific: line 75
Follow existing patterns (see payment_category or expense_category)
- Very specific: line 78
Add database model to modules/{module}/infrastructure/persistence/models/models.go
- Very specific: line 79
Create repository implementation in modules/{module}/infrastructure/persistence/{entity_name}_repository.go
- Very specific: line 80
Add domain-to-database mappers in modules/{module}/infrastructure/persistence/{module}_mappers.go
- Very specific: line 83
Create service in modules/{module}/services/{entity_name}_service.go
- Very specific: line 85
Follow constructor pattern: NewEntityService(repo, eventPublisher)
- Very specific: line 88
Create DTOs in modules/{module}/presentation/controllers/dtos/{entity_name}_dto.go
- Very specific: line 89
Create controller in modules/{module}/presentation/controllers/{entity_name}_controller.go
- Very specific: line 90
Create viewmodel in modules/{module}/presentation/viewmodels/{entity_name}_viewmodel.go
- Very specific: line 91
Add mapper in modules/{module}/presentation/mappers/mappers.go
- Very specific: line 94
Create templ files in modules/{module}/presentation/templates/pages/{entity_name}/
- Very specific: line 96
Run templ generate after creating/modifying .templ files
- Very specific: line 99
Add translations to all locale files in modules/{module}/presentation/locales/
- Very specific: line 103
Add navigation item to modules/{module}/links.go
- Very specific: line 106
Use composition.ProvideFuncAs[Interface] when a constructor returns a concrete type but you want the provider keyed by an interface
- Very specific: line 107
Add controllers with composition.ContributeControllersFunc(...) or composition.AddControllers(...) for pre-built instances
- Very specific: line 112
Run go vet ./... to verify compilation
- Very specific: line 113
Run templ generate && just css if templates were modified
- Very specific: line 124
Multi-tenant isolation: Always include tenant_id in WHERE clauses
- Very specific: line 125
Error handling: Use pkg/serrors - serrors.Wrap(op, err) pattern
- Very specific: line 126
HTMX: Check htmx.IsHxRequest(r), use htmx.SetTrigger(w, "event", payload)
- Very specific: line 130
DO NOT USE sed for file manipulation
- Very specific: line 137
Every PR adds .changes/<name>.json with bump (none, patch, minor, or major) and a non-empty summary.
- Distinctive: line 139
Do not push version tags manually.
- Very specific: line 150
Check translation files: just check tr
- Very specific: line 153
After changes to css or .templ files: templ generate && just css
- Very specific: line 154
After changes to Go code: go vet ./...
- Very specific: line 155
Never run
go build: - use go vet instead - Very specific: line 156
Run all tests: just test -v or go test -v ./...
- Very specific: line 157
Run single test: go test -v ./path/to/package -run TestName
- Very specific: line 158
Run specific subtest: go test -v ./path/to/package -run TestName/SubtestName
- Distinctive: line 172
Read docs/agent-sign-in.md for setup, controller registration, and consumer CLI integration.
- Very specific: line 185
Use go fmt for formatting.
- Distinctive: line 186
Use Go v1.24.10 and follow standard Go idioms
- Very specific: line 191
When writing a mapper function, always use utilities from pkg/mapping to ensure consistency
- Distinctive: line 193
Follow existing patterns for database operations with jmoiron/sqlx
- Very specific: line 198
Use pkg/htmx for all UI interactions
- Very specific: line 199
Use existing components from components/ package before creating new ones
- Very specific: line 202
Use htmx.IsHxRequest(r) to check if a request is from HTMX
- Very specific: line 203
Use htmx.SetTrigger(w, "eventName", payload) for setting HTMX response triggers
≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md - IOTA SDK Guide
Overview
DO NOT COMMENT EXECESSIVELY. Instead, write clear and concise code that is self-explanatory.
Design Philosophy
iota-sdk is a general purpose ERP building engine/solution. When designing anything inside iota-sdk:
- Make it extensible, generalizable, and customizable
- Prefer interfaces over concrete structs at boundaries
- Apply dependency inversion and inject interfaces
- Keep domain and services decoupled from infrastructure details
SDK and consumer ownership
Before adding a consumer workaround for shared SDK behavior, trace the SDK API, available extension points, and affected consumers. Fix a reusable capability or invariant in the SDK; when a consumer exposed the defect, validate the fix in that consumer's preview workflow. Keep product-specific policy and workflow in the consumer. Decide from the actual ownership boundary, not from which repository first exposed the defect.
Module Architecture
Each module follows a strict Domain-Driven Design (DDD) pattern with clear layer separation:
modules/{module}/
├── domain/ # Pure business logic
│ ├── aggregates/{entity}/ # Complex business entities
│ │ ├── {entity}.go # Entity interface
│ │ ├── {entity}_impl.go # Entity implementation
│ │ ├── {entity}_events.go # Domain events
│ │ └── {entity}_repository.go # Repository interface
│ ├── entities/{entity}/ # Simpler domain entities
│ └── value_objects/ # Immutable domain concepts
├── infrastructure/ # External concerns
│ └── persistence/
│ ├── models/models.go # Database models
│ ├── {entity}_repository.go # Repository implementations
│ ├── {module}_mappers.go # Domain-to-DB mapping
│ ├── schema/{module}-schema.sql # SQL schema
│ └── setup_test.go # Test utilities
├── services/ # Business logic orchestration
│ ├── {entity}_service.go # Service implementation
│ ├── {entity}_service_test.go # Service tests
│ └── setup_test.go # Test setup
├── presentation/ # UI and API layer
│ ├── controllers/
│ │ ├── {entity}_controller.go # HTTP handlers
│ │ ├── {entity}_controller_test.go # Controller tests
│ │ ├── dtos/{entity}_dto.go # Data transfer objects
│ │ └── setup_test.go # Test utilities
│ ├── templates/
│ │ ├── pages/{entity}/ # Entity-specific pages
│ │ │ ├── list.templ # List view
│ │ │ ├── edit.templ # Edit form
│ │ │ └── new.templ # Create form
│ │ └── components/ # Reusable UI components
│ ├── viewmodels/ # Presentation models
│ ├── mappers/mappers.go # Domain-to-presentation mapping
│ └── locales/ # Internationalization
│ ├── en.json # English translations
│ ├── ru.json # Russian translations
│ └── uz.json # Uzbek translations
├── module.go # Module registration
├── links.go # Navigation items
└── permissions/constants.go # RBAC permissionsCreating New Entities (Repositories, Services, Controllers)
1. Domain Layer
- Create domain entity in
modules/{module}/domain/aggregates/{entity_name}/ - Define repository interface with CRUD operations and domain events
- Follow existing patterns (see
payment_categoryorexpense_category)
2. Infrastructure Layer
- Add database model to
modules/{module}/infrastructure/persistence/models/models.go - Create repository implementation in
modules/{module}/infrastructure/persistence/{entity_name}_repository.go - Add domain-to-database mappers in
modules/{module}/infrastructure/persistence/{module}_mappers.go
3. Service Layer
- Create service in
modules/{module}/services/{entity_name}_service.go - Include event publishing and business logic methods
- Follow constructor pattern:
NewEntityService(repo, eventPublisher)
4. Presentation Layer
- Create DTOs in
modules/{module}/presentation/controllers/dtos/{entity_name}_dto.go - Create controller in
modules/{module}/presentation/controllers/{entity_name}_controller.go - Create viewmodel in
modules/{module}/presentation/viewmodels/{entity_name}_viewmodel.go - Add mapper in
modules/{module}/presentation/mappers/mappers.go
5. Templates (if needed)
- Create templ files in
modules/{module}/presentation/templates/pages/{entity_name}/ - Common templates:
list.templ,edit.templ,new.templ - Run
templ generateafter creating/modifying .templ files
6. Localization
- Add translations to all locale files in
modules/{module}/presentation/locales/ - Include NavigationLinks, Meta (titles), List, and Single sections
7. Registration
- Add navigation item to
modules/{module}/links.go - Register the module in
modules/{module}/component.go:- Register repositories and services with
composition.ProvideFunc(...)— the reflection injector resolves each constructor parameter from the container by type (no manual lookup) - Use
composition.ProvideFuncAs[Interface]when a constructor returns a concrete type but you want the provider keyed by an interface - Add controllers with
composition.ContributeControllersFunc(...)orcomposition.AddControllers(...)for pre-built instances - Attach static contributions via
composition.AddNavItems,composition.AddQuickLinks,composition.AddHashFS - Declare locale files on the component itself via the required
LocaleFS()method; the engine wires them automatically.
- Register repositories and services with
8. Verification
- Run
go vet ./...to verify compilation - Run
templ generate && just cssif templates were modified
Technology Stack
- Backend: Go 1.24.10, IOTA SDK framework, GraphQL
- Database: PostgreSQL 13+ (multi-tenant with organization_id)
- Frontend: HTMX + Alpine.js + Templ + Tailwind CSS
- Auth: Cookie-based sessions with RBAC
Core Rules
- Multi-tenant isolation: Always include
tenant_idin WHERE clauses - Error handling: Use
pkg/serrors-serrors.Wrap(op, err)pattern - HTMX: Check
htmx.IsHxRequest(r), usehtmx.SetTrigger(w, "event", payload) - Templ: Edit
.templsources, not generated*_templ.gofiles. Inspect generated diffs or compiler errors when validating a change, and exclude unrelated generator churn.
Tool Use
- DO NOT USE
sedfor file manipulation - For code navigation, use symbol references/definitions when available; use
rg --filesfor paths andrgfor text.
Build/Lint/Test Commands
SDK release workflow
Every PR adds .changes/<name>.json with bump (none, patch, minor, or
major) and a non-empty summary. Existing declarations are append-only.
Do not push version tags manually. PRs run service-free checks; a consumer request
runs full CI on an immutable candidate before publication. Use
sdk-tools sdk use <SDK-PR> for preview and sdkctl promote
to wait for a verified release and update local production dependencies. See docs/sdk-releases.md.
Quality commands
Code Quality Commands:
- Format Go code and templates:
just fix fmt - Organize and format Go imports:
just fix imports - Lint code (check unused variables/functions):
just check lint - Check translation files:
just check tr
Other Commands:
- After changes to css or .templ files:
templ generate && just css - After changes to Go code:
go vet ./... - Never run
go build- usego vetinstead - Run all tests:
just test -vorgo test -v ./... - Run single test:
go test -v ./path/to/package -run TestName - Run specific subtest:
go test -v ./path/to/package -run TestName/SubtestName - Apply migrations:
just db migrate up
Local browser sign-in for agents
For manual browser verification against a local development database, use the
SDK's agent sign-in --user <ID-or-email> --next /internal/path --output json
CLI command and open the returned URL in the agent's browser within one minute.
Each link works once; issue a fresh one for retries or another account. Choose
an existing user with the roles required by the task; their permissions remain
unchanged.
Both CLI and server require -tags dev, APP_ENVIRONMENT=development, and
AGENT_SIGNIN_ENABLED=true, the same OS user, loopback origin and tenant.
Read docs/agent-sign-in.md for setup, controller
registration, and consumer CLI integration. Use this flow only for local
development.
E2E Testing
just e2e run # Interactive UI mode
just e2e ci # Headless CI mode
cd e2e && npx playwright test tests/module/specific.spec.ts # Single testCode Style Guidelines
- Use
go fmtfor formatting. Do not indent code manually. - Use Go v1.24.10 and follow standard Go idioms
- File organization: group related functionality in modules/ or pkg/ directories
- Naming: use camelCase for variables, PascalCase for exported functions/types
- Testing: table-driven tests with descriptive names (TestFunctionName_Scenario), use the
requireandassertpackages fromgithub.com/stretchr/testify - Error handling: use
pkg/serrorswith patternserrors.Wrap(op, err)for standard error types - When writing a mapper function, always use utilities from
pkg/mappingto ensure consistency - Type safety: use strong typing and avoid interface{} where possible
- Follow existing patterns for database operations with jmoiron/sqlx
- For UI components, follow the existing templ/htmx patterns
UI Implementation Guidelines
- Use
pkg/htmxfor all UI interactions - Use existing components from
components/package before creating new ones
HTMX Best Practices
- Use
htmx.IsHxRequest(r)to check if a request is from HTMX - Use
htmx.SetTrigger(w, "eventName", payload)for setting HTMX response triggers
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 28,693 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository6 other files it gives its agents.
- .claude/guides/claude-code/agents.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- Database ConnectionSkill
- E2E TestingSkill
- Railway CLISkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

