

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# AGENTS.md23Guidance for AI coding agents working on the Neptune project.45---67## Project Overview89**Neptune** is a Terraform and OpenTofu pull request automation tool inspired by [Atlantis](https://github.com/runatlantis/atlantis). It runs plan/apply (Terraform or OpenTofu) on pull requests using the [Terramate](https://github.com/terramate-io/terramate) Go SDK for change detection and run order. When a step has `once` false or unset (default), Neptune runs the step’s command in each changed stack (Terramate SDK or local stacks; no Terramate CLI needed when using Terramate); object storage (GCS or S3) is used for stack locking, and GitHub for PR requirements and comments.1011**Main capabilities**: Load config from `.neptune.yaml` and env; in CI (non-E2E), config is loaded from the repository’s default branch via git (fallback to PR branch) so PR authors cannot change workflow steps; check PR requirements (approved, mergeable, undiverged, rebased); lock stacks in object storage (GCS, AWS S3, or S3-compatible e.g. MinIO); run workflow steps (per-stack by default, or once in root when `once: true`); for stacks_management: local, **neptune stacks** provides list (--changed) and create, with **--format** (json, yaml, text, formatted; default formatted); when using discovery, run order can be set via **depends_on** in each **stack.hcl** (path-only; relative paths and directory-of-stacks supported); post results as PR comments. Optional `repository.automerge: true` enables PR auto-merge after a successful apply (GitHub GraphQL). Log level is configurable via `log_level` (config), `NEPTUNE_LOG_LEVEL`, or the global **--log-level** CLI flag (DEBUG, INFO, ERROR).1213**Language**: Go (see `go.mod`).1415---1617## Repository Structure1819- **`main.go`** – Entry point; version/commit/date via ldflags.20- **`cmd/`** – CLI (Cobra): `root.go` (global **--log-level** flag), `version.go`, `command.go`, `unlock.go`, `stacks.go` (stacks list, create; **--format** json|yaml|text|formatted, default formatted; **neptune stacks create** supports optional **--depends-on** comma-separated paths). **neptune stacks list** and **neptune stacks create** are for local use and do not require `GITHUB_TOKEN` or other CI env vars (unlike **neptune command** and **neptune unlock**).21- **`internal/config`** – Load env + YAML, validate `.neptune.yaml` (including optional `log_level`, `stacks_management`, root-level `local_stacks`).22- **`internal/domain`** – Config, lock, run, and GitHub domain structs (WorkflowStep uses `once`; RepositoryConfig has `StacksManagement`, `LocalStacks`).23- **`internal/log`** – Structured logging (DEBUG, INFO, ERROR) via `log/slog`; level from `NEPTUNE_LOG_LEVEL` or config `log_level`.24- **`internal/stacks`** – Stacks provider interface (terramate, local); list/changed stacks for locking and runner.25- **`internal/lock`** – Lock interface: gets stack list from stacks provider, object-storage lock files (GCS, S3).26- **`internal/run`** – Execute workflow phase steps (shell).27- **`internal/github`** – GitHub API client, PR requirements (approved, mergeable, undiverged), commit statuses (GetHeadSHA, CreateCommitStatus) for **neptune plan** / **neptune apply**; GraphQL EnablePullRequestAutoMerge when `repository.automerge` is true.28- **`internal/git`** – Rebased check; DefaultBranch (git CLI), ShowFileFromRef, FetchBranch for loading config from default branch.29- **`internal/notifications/github`** – Format and post PR comments.30- **`examples/`** – Infra examples (S3/GCS backend, automerge, Terramate stacks, Terragrunt).31- **`scripts/`** – Maintainer scripts (if any).32- **`e2e/`** – End-to-end tests: three Terramate stacks (null_resource/local_file), MinIO via Docker Compose, and `scripts/run-terramate.sh` that runs Neptune plan/apply with `NEPTUNE_E2E=1` (skips GitHub; see [e2e/README.md](e2e/README.md)).33- **`lambda/`** – AWS Lambda handler for Neptune GitHub App webhooks (verify signature, parse `pull_request`—including `labeled` when the added label is `NEPTUNE_PR_LABEL`—and `issue_comment`, trigger `repository_dispatch`; optional `NEPTUNE_PR_LABEL` gates on PR label). See [lambda/README.md](lambda/README.md).34- **`lambda/cloudformation/`** – CloudFormation template to deploy the Lambda (Function URL, IAM, Secrets Manager). See [lambda/README.md](lambda/README.md#deploy-with-cloudformation).35- **`Makefile`**, **`.golangci.yml`**, **`.goreleaser.yml`**, **`.github/workflows/`** – Build, test, lint, release.36- **`.claude/agents/` (migrated to hub)** – Agent definitions have been moved to the [code-agent-hub](https://github.com/devopsfactory-io/code-agent-hub) at `.claude/agents/neptune/`. Agents include: documentation-maintainer, em, go-developer, iac-developer, issue-reviewer, issue-writer, platform-engineering, pr-reviewer, qa, security.37- **`.claude/commands/`** – Claude slash commands: `/feature`, `/bug` (invoke the issue-writer workflow to create issues from the repo’s issue templates; the draft is validated by issue-reviewer before `gh issue create`).38- **Root community docs**: [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md), [SECURITY.md](SECURITY.md), [GOVERNANCE.md](GOVERNANCE.md), [MAINTAINERS.md](MAINTAINERS.md), [ROADMAP.md](ROADMAP.md), [LICENSE](LICENSE).3940---4142## Setup Commands4344```bash45# Build binary46make build4748# Run all tests (main module)49make test-all5051# Lambda (separate module under lambda/): build, package, test52make lambda.build53make lambda.zip54make lambda.test5556# Check Go formatting (includes lambda/)57make check-fmt5859# Lint (optional; requires golangci-lint)60make lint61```6263Use Go version from `go.mod`. No other prerequisites for building or testing the Go CLI. CI runs `make test-all`, `make lambda.test`, and `make check-fmt`.6465---6667## Code Style6869- **Format**: Use `gofmt -s`; run `make check-fmt` before committing.70- **Linting**: `.golangci.yml` is authoritative; do not introduce new linter violations.71- **Packages**: Code under `internal/` must not be imported from outside this module.72- **Errors**: Return errors with context (e.g. `fmt.Errorf("...: %w", err)`); avoid naked returns.73- **Exports**: Public functions and types should have doc comments starting with the name.7475---7677## Testing7879- **Run**: `go test ./...` or `make test-all`.80- **Location**: Place `*_test.go` next to the code under test (same package).81- **Coverage**: Existing tests cover `internal/config`, `internal/git`, `internal/github`, `internal/run`, `internal/notifications/github`; add tests for new behavior and keep coverage for touched code.82- **No external services**: Unit tests should not require live GitHub or GCS; mock or stub as needed.83- **E2E**: Run `make e2e` or `./e2e/scripts/run-terramate.sh` (requires Docker, Terraform). Uses MinIO and `NEPTUNE_E2E=1` to skip GitHub. For **stacks_management: local**, run `./e2e/scripts/run-local-stacks-files.sh` or `./e2e/scripts/run-local-declared-stacks.sh`. E2E config uses steps with default `once: false` (Neptune runs commands per stack).84- **Automerge**: E2E and integration tests in this repo do not exercise the automerge feature. A separate repository (e.g. a fork or copy of [examples/](examples/)) can be used to test automerge end-to-end (e.g. open a PR with changes in two stacks, comment `@neptbot apply`, then verify the apply comment and that the PR is set to auto-merge after checks pass).8586---8788## CI8990- **`.github/workflows/test.yml`** – On push to `main`/`release-*` and on PRs; path filter for Go files; runs `make test-all` and `make check-fmt`.91- **`.github/workflows/e2e.yml`** – On push/PR when e2e-related paths change; runs `./e2e/scripts/run-terramate.sh` with MinIO (Docker Compose). See [e2e/README.md](e2e/README.md).92- **`.github/workflows/integration.yml`** – On PRs when integration-relevant paths change; runs Neptune plan/apply on the same PR with real GitHub (requirements check, PR comments, commit statuses) and MinIO for locks. Needs `statuses: write` for commit status API. See [e2e/README.md](e2e/README.md#integration-tests).93- **`.github/workflows/cross-repo-test.yml`** – On PRs (non-draft) to `main`/`release-*` when core paths change (`e2e/**`, `cmd/**`, `internal/**`, `lambda/**`, `go.*`); runs cross-repo integration tests against the external `neptune-tests` repository. Creates dynamic Terramate stacks on a throwaway branch in `neptune-tests`, opens a test PR with a `neptune-ref` marker, waits for neptbot to execute the full plan/apply webhook flow (up to 10 minutes each), verifies commit statuses (`neptune plan`, `neptune apply`), checks automerge state, and cleans up the branch and PR. Uses the `neptune-ci` GitHub App (secrets: `NEPTUNE_CI_APP_ID`, `NEPTUNE_CI_PRIVATE_KEY`) for cross-repo operations. Runs in parallel with `e2e.yml` and `integration.yml`.94- **`.github/workflows/lint.yml`** – On PRs; path filter for Go; runs golangci-lint.95- **`.github/workflows/labeler.yml`** – On pull_request (opened, synchronize, reopened); runs [actions/labeler](https://github.com/actions/labeler) with [.github/labeler.yml](.github/labeler.yml). Path-based: neptune, dependencies, documentation. Head-branch (branch name): `feat*`→feature, `enhance*`→enhancement, `fix*` (not fix*dep*)→bug, branch containing `!`→breaking-change, `ci*`→github-actions, `(deps)`→dependencies. See CONTRIBUTING.md for contributor-facing branch naming.96- **`.github/workflows/label-old-prs.yml`** – workflow_dispatch; applies the labeler to existing PRs (inputs: state e.g. merged/closed/all, limit). Use to backfill labels on old or merged PRs (Actions → "Label old PRs" → Run workflow). Because the labeler does not receive branch context on workflow_dispatch, a separate step applies the same rules as `.github/labeler.yml` to both head branch and PR title (e.g. `feat*`→feature if either branch or title matches), then the labeler runs for path-based labels.97- **`.github/workflows/release.yml`** – On push of tags `v*.*.*` (and workflow_dispatch); runs GoReleaser to create GitHub Release with neptune binaries (archives e.g. `neptune_linux_amd64.tar.gz` and raw binaries e.g. `neptune_linux_amd64`), Lambda zip (`neptune-webhook.zip`) and raw binary `neptune-webhook_linux_amd64` (Lambda binary is `neptune-webhook`; zip contains it), checksums, and release notes. The release body is generated by **GitHub** (GoReleaser uses `changelog.use: github-native`) and categorized using [.github/release.yml](.github/release.yml) and PR labels (Breaking Changes, Features, Bug fixes, Documentation, Dependency updates, Other work). Release footer includes Full Changelog link.98- **Renovate** – Dependency-update PRs (Go modules and GitHub Actions) are opened by [Renovate](https://docs.renovatebot.com/) from [.github/renovate.json5](.github/renovate.json5). To enable Renovate, install the [Renovate GitHub App](https://github.com/apps/renovate) and select the repo. Do not remove or override this config without reason.99100Semantic versioning: use tags like `v0.2.0`. GoReleaser injects version/commit/date into the binary via ldflags.101102**Changelog and breaking changes**: The release body is generated by GitHub (github-native) and categorized by [.github/release.yml](.github/release.yml) and **PR labels**. For breaking changes to appear under "Breaking Changes", apply the `breaking-change` label to the PR before merge. The commit subject convention (`!:`) is still recommended for semver (e.g. `feat!: remove deprecated flag`) but does not drive release-note sections; labels do.103104---105106## Documentation and AI Context (Mandatory)107108After any change that affects behavior, APIs, config, or CI:1091101. **Delegate**: Delegate documentation updates to the **documentation-maintainer** agent (defined in the hub at `.claude/agents/neptune/documentation-maintainer/`) so it runs the full maintain-documentation checklist (README, docs/, examples/, AGENTS.md, CLAUDE.md, .claude/commands, .claude/skills).1112. **Do not edit plan files** (e.g. `neptune_go_rewrite*.plan.md` or `ai_agent_config*.plan.md`) unless the user explicitly asks.112113When in doubt, update. See `CLAUDE.md` (Documentation rule, always applies) and the **maintain-documentation** skill (`.claude/skills/maintain-documentation/`); the agent holds the detailed checklist.114115---116117## PR Guidance118119Before submitting:1201211. **Commits must be signed off (DCO).** Use `git commit -s` when creating commits. Do not add a `Made-with: Cursor` (or similar) trailer to commit messages. If you already committed without sign-off, run `git commit --amend -s --no-edit` then force-push. See [CONTRIBUTING.md](CONTRIBUTING.md) and `CLAUDE.md` (DCO rule).1222. Run `make test-all` and `make check-fmt`.1233. Ensure no new linter errors (`make lint` if available).1244. If behavior or setup changed, delegate to the **documentation-maintainer** subagent.1255. **Branch naming**: Branch names matching [.github/labeler.yml](.github/labeler.yml) (e.g. `feat/...`, `fix/...`, `enhance/...`, `(deps)/...`, `ci/...`, or branch containing `!` for breaking) get PR labels applied automatically, which drive release-note categories. See [CONTRIBUTING.md](CONTRIBUTING.md#branch-naming-and-pr-labels).126127PR titles may follow a conventional style (e.g. `feat(cmd): ...`, `fix(lock): ...`, `docs: ...`) but this is not enforced.128129---130131## References132133- **Contributing (human)**: [CONTRIBUTING.md](CONTRIBUTING.md) – main entry for contributors; [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md), [SECURITY.md](SECURITY.md); issue and PR templates in [.github/ISSUE_TEMPLATE/](.github/ISSUE_TEMPLATE/) and [.github/pull_request_template.md](.github/pull_request_template.md).134- **Governance**: [GOVERNANCE.md](GOVERNANCE.md), [MAINTAINERS.md](MAINTAINERS.md), [ROADMAP.md](ROADMAP.md).135- **Claude project rules**: `CLAUDE.md` – mandatory rules (DCO, Go standards, CI/release, config schema) embedded as project instructions.136- **Claude commands**: `.claude/commands/` – slash commands (e.g. `/feature`, `/bug`) that trigger the issue-writer workflow. Drafts are validated by issue-reviewer before creation.137- **Claude skills**: `.claude/skills/` – workflows for documentation maintenance, releases, testing, and open-pull-request (open a PR from current changes via gh CLI).138- **Getting started**: [docs/getting-started-terramate.md](docs/getting-started-terramate.md) and [docs/getting-started-local-stacks.md](docs/getting-started-local-stacks.md) – onboarding with GitHub Actions and neptbot (Terramate or local stacks).139- **Neptune config**: [docs/configuration.md](docs/configuration.md) and [.neptune.example.yaml](.neptune.example.yaml) for `.neptune.yaml` schema; [docs/object-storage.md](docs/object-storage.md) for backend env vars.140- **Why Neptune / workflow comparison**: [docs/workflow-comparison.md](docs/workflow-comparison.md) – comparison of normal Terraform + GitHub Actions, Neptune, and Atlantis; use when explaining rationale for apply-before-merge.141
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| devopsfactory-io/neptune.cursor/rules/ci-and-release.mdc · 3 | Cursor rules | deployment | 45/100 | 14 days ago | |
| devopsfactory-io/neptune.cursor/rules/commits-dco.mdc · 3 | Cursor rules | gitdo-not | 38/100 | 14 days ago | |
| devopsfactory-io/neptune.cursor/rules/config-and-yaml.mdc · 3 | Cursor rules | no sections | 16/100 | 14 days ago | |
| devopsfactory-io/neptune.cursor/rules/docs-and-ai-context.mdc · 3 | Cursor rules | docs | 16/100 | 14 days ago | |
| devopsfactory-io/neptune.cursor/rules/go-standards.mdc · 3 | Cursor rules | lint-format | 35/100 | 14 days ago | |
| devopsfactory-io/neptune.cursor/rules/issue-creation.mdc · 3 | Cursor rules | no sections | 24/100 | 14 days ago | |
| devopsfactory-io/neptuneCLAUDE.md · 3 | CLAUDE.md | lint-formatstyletypestesting-strategy+5 | 89/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 201k | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| aaif-goose/gooseAGENTS.md · 53k | AGENTS.md | setupbuildtestlint-format+7 | 100/100 | 8 days ago | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| deepseek-ai/deepseek-harnessnative/landlock-run/AGENTS.md · 104k | AGENTS.md | setupteststylearch+3 | 100/100 | today | |
| code-yeongyu/oh-my-openagentpackages/web/AGENTS.md · 68k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 13 days ago | |
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | today | |
| vllm-project/vllmAGENTS.md · 89k | AGENTS.md | setuptestlint-formatstyle+5 | 100/100 | 14 days ago | |
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/devopsfactory-io-neptune-agents)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.