diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index ad39538..8e03c00 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -1,33 +1,102 @@ -# Project Guidelines +# Project Guidelines — mattermost-plugin-alertmanager + +Guidance for any Claude agent working in this repo. Read it before changing +code, docs, or CI. It captures invariants that are easy to break silently. ## Overview - - -## Architecture - - -## Coding Conventions -- Follow existing patterns in the codebase -- Match the style of surrounding code -- Use meaningful variable and function names -- Keep functions focused and small - -## Testing -- Write tests for new functionality -- Run existing tests before submitting changes -- Aim for meaningful coverage of critical paths - -## Git Workflow -- Create feature branches for new work -- Write clear, descriptive commit messages -- Keep commits focused on a single change - -## Error Handling -- Handle errors explicitly, don't ignore them -- Provide context when wrapping errors -- Log errors at appropriate levels - -## Dependencies -- Prefer standard library solutions when available -- Evaluate dependencies for maintenance and security -- Keep dependencies up to date + +Server-only Mattermost plugin that bridges Prometheus Alertmanager → Mattermost +via native incoming webhooks. The daily-use value: when an alert fires, the post +includes the matching runbook's first three diagnostic commands inline, +pre-filled with the failing host/pod from the alert's labels. + +- **Enterprise Edition only.** Deploy/test against `mattermost-enterprise-edition`, never team-edition. +- **No webapp bundle.** `plugin.json` has a `server` block only. This rules out + System Console `type: "custom"` settings and any React UI. Settings are the + flat `settings_schema` — there is **no conditional show/hide** between settings. + +## Architecture (key paths) + +- `server/` — the Go plugin. Table-driven tests, stdlib only (no testify). +- `runbooks/*.md` — the 30 canonical SRE runbooks, embedded via `//go:embed` (`runbooks_embed.go`). +- `docs/*.md` — embedded docs, shown in chat (`/alertmanager docs`) and rendered to HTML. +- `samples/prometheus-rules.yaml` — the shipped example rules. **Single source of truth** for the in-plugin rules page. +- `build/render-docs/main.go` — renders `docs/*.md` + `runbooks/*.md` **and** `samples/prometheus-rules.yaml` → `public/*.html` at bundle time. Its own Go module. +- `public/` — **generated** (`make render-docs`, run by `make bundle`). Gitignored. Never hand-edit; edit the source + regenerate. +- `plugin.json` — manifest + System Console `settings_schema` (header/footer/settings). +- `.github/workflows/` — `lint`, `test`, `build`, `security`, `release-please`, `pages`, `release`. + +## The catalog and the "keep every count in sync" rule + +The catalog is **30 runbooks / 31 rules** (`ContainerOOMKilled` reuses the +`high-memory-usage` runbook, so one extra rule than runbooks). A recurring bug in +this repo has been stale hardcoded counts ("20 runbooks") left behind when the +catalog grew. **When the catalog changes, update every mirror in the same PR:** + +- `plugin.json` (header, footer, `add`/`remove`/`validate` autocomplete help) +- `README.md` +- `docs/` (ALERT_CATALOG, ALERT_REQUIREMENTS, etc.) and the `runbookIndexBody` in `build/render-docs/main.go` +- `samples/prometheus-rules.yaml` (one rule per runbook) and deploy-local's copy +- Go comments that name a count (`admin_inventory.go`, `cmd_query.go`) +- `scaffoldSets` in `server/cmd_scaffold.go` (category → slugs) + +**Drift guards already enforce most of this** — run `go test ./server/...`: +- `TestScaffoldMatchesRunbookFiles` — every scaffold slug has a runbook file and vice versa. +- `TestScaffoldCategoriesDocumented` — every category appears in help text + autocomplete. +- `TestRunbookPlaceholdersAllowlisted` — runbook `