Skip to content

Commit 8089a3c

Browse files
committed
HYPERFLEET-930 - chore: bump pre-commit version
1 parent 2ffff68 commit 8089a3c

2 files changed

Lines changed: 26 additions & 93 deletions

File tree

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ default_install_hook_types: [pre-commit, commit-msg]
22

33
repos:
44
- repo: https://github.com/openshift-hyperfleet/hyperfleet-hooks
5-
rev: v0.1.0
5+
rev: v0.2.1
66
hooks:
77
- id: hyperfleet-commitlint
88
stages: [commit-msg]

AGENTS.md

Lines changed: 25 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,16 @@
1-
# CLAUDE.md
1+
# HyperFleet Sentinel
22

3-
## Project Identity
3+
Kubernetes resource watcher — polls HyperFleet API for cluster/nodepool updates, makes orchestration decisions via CEL-based decision logic, publishes CloudEvents to message brokers. Stateless, horizontally scalable via label-based sharding, delegates all state persistence to API.
44

5-
HyperFleet Sentinel is a **Kubernetes resource watcher** that polls the HyperFleet API for cluster/nodepool updates, makes orchestration decisions via CEL-based decision logic, and publishes CloudEvents to message brokers. Stateless, horizontally scalable via label-based sharding, delegates all state persistence to the API.
5+
Go 1.25 · Broker abstraction (RabbitMQ, GCP Pub/Sub, Stub) · Helm chart in `charts/`
66

7-
- **Language**: Go 1.25 (see `go.mod`)
8-
- **Messaging**: Broker abstraction (RabbitMQ, GCP Pub/Sub, Stub)
9-
- **API Client**: Generated from [hyperfleet-api-spec](https://github.com/openshift-hyperfleet/hyperfleet-api-spec) — see [openapi/README.md](openapi/README.md)
10-
- **Deployment**: Helm chart in `charts/`
11-
12-
Sentinel is one component in the HyperFleet control plane:
13-
- **API** — persists cluster/nodepool state (source of truth)
14-
- **Sentinel** — watches API, decides when resources need reconciliation, publishes events
15-
- **Adapters** — consume events, execute provisioning/deprovisioning, report back to API
16-
- **Broker** (RabbitMQ or Pub/Sub) — decouples Sentinel from adapters
17-
18-
## Critical First Steps
19-
20-
**Generated OpenAPI client is NOT committed to git.** Before any build, test, or development task:
21-
22-
```bash
23-
make generate # Extracts OpenAPI spec from hyperfleet-api-spec module and generates Go client
24-
```
25-
26-
Setup sequence for a fresh clone:
27-
1. `make generate` — generate OpenAPI client in `pkg/api/openapi/`
28-
2. `make download` — fetch Go dependencies
29-
3. `make build` — build `bin/sentinel` binary
30-
4. `make test` — verify unit tests pass
7+
**Generated OpenAPI client is NOT committed to git.** Run `make generate` before any build, test, or development task.
318

329
## Verification
3310

3411
| Command | What it does |
3512
|---|---|
13+
| `make generate` | Extract OpenAPI spec from hyperfleet-api-spec module, generate Go client |
3614
| `make verify` | go vet + format check (fast) |
3715
| `make lint` | golangci-lint (comprehensive) |
3816
| `make test` | all tests (`./...`), writes `coverage.out` profile |
@@ -44,14 +22,18 @@ Setup sequence for a fresh clone:
4422

4523
Quick feedback: `make verify && make test-unit`. Full pre-push: `make test-all`.
4624

47-
**PR pre-flight order:**
48-
1. `make generate`
49-
2. `make fmt`
50-
3. `make lint`
51-
4. `make test-unit`
52-
5. `make test-integration` — if broker/API changes
53-
6. `make test-helm` — if chart changes
54-
7. Update CHANGELOG.md if the change is user-visible
25+
Setup sequence for a fresh clone:
26+
1. `make generate` — generate OpenAPI client in `pkg/api/openapi/`
27+
2. `make download` — fetch Go dependencies
28+
3. `make install-hooks` — install pre-commit hooks
29+
4. `make build` — build `bin/sentinel` binary
30+
5. `make test` — verify unit tests pass
31+
32+
## CLI
33+
34+
Subcommands: `sentinel serve`, `sentinel config-dump`, `sentinel version`. Config path via `--config`. All flags have env var equivalents (`HYPERFLEET_*` prefix) — run `sentinel serve --help`.
35+
36+
Config precedence (highest wins): CLI flags > env vars > YAML file > defaults. Broker credentials handled separately via `broker.yaml` (or `BROKER_CONFIG_FILE` env var).
5537

5638
## Source of Truth
5739

@@ -72,7 +54,7 @@ Quick feedback: `make verify && make test-unit`. Full pre-push: `make test-all`.
7254

7355
## Architecture Context
7456

75-
Sentinel's job: **decide when**, not **execute how**. It can be killed and restarted at any time without data loss — this is what makes label-based sharding safe. The `message_decision` config uses CEL expressions to decide when to publish — see `DefaultMessageDecision()` in `internal/config/config.go` for default expressions.
57+
Sentinel's job: **decide when**, not **execute how**. Can be killed and restarted at any time without data loss — this is what makes label-based sharding safe. `message_decision` config uses CEL expressions to decide when to publish — see `DefaultMessageDecision()` in `internal/config/config.go`.
7658

7759
### Key Internal Patterns
7860
- **Config validation fails fast**`Validate()` returns error at startup, `LoadConfig()` propagates to main which exits non-zero
@@ -81,79 +63,30 @@ Sentinel's job: **decide when**, not **execute how**. It can be killed and resta
8163

8264
## Code Conventions
8365

84-
### Commit Messages
85-
Format: `HYPERFLEET-### - type: description`
86-
87-
Example:
88-
```
89-
HYPERFLEET-427 - feat: add standard metrics labels
90-
91-
Adds resource_type and resource_selector labels to all
92-
Prometheus metrics for consistent querying.
93-
94-
Co-Authored-By: Claude <noreply@anthropic.com>
95-
```
96-
Co-Authored-By trailer required on all Claude-assisted commits.
97-
98-
### Configuration
99-
- Config struct in `internal/config/config.go` — YAML struct tags, validation via `Validate()`
100-
- All durations use `time.Duration` with YAML `duration` format (e.g., `5s`, `30m`)
101-
- Config precedence (highest wins): CLI flags > env vars (`HYPERFLEET_*`) > YAML file > defaults
102-
- Broker credentials handled separately via `broker.yaml` (or `BROKER_CONFIG_FILE` env var)
103-
104-
### CLI Commands
105-
- `sentinel serve --config config.yaml` — run the service
106-
- `sentinel config-dump --config config.yaml` — print merged config (debug precedence issues)
107-
- `sentinel version` — print version, commit, build date
108-
- Run `sentinel serve --help` for full flag list
109-
11066
### Error Handling
11167
- Log at boundaries (main service loop), not deep in call stack
11268

11369
### Logging
114-
- Custom structured logger in `pkg/logger/` — stdlib only, no external deps
115-
- Interface: `logger.HyperFleetLogger` with `Info()`, `Error()`, `Warn()`, `Debug()`, `V(level)` (verbosity), `Extra()`
116-
- Create via `logger.NewHyperFleetLogger()` — uses global config
117-
- Chaining: `logger.Extra("key", val).Extra("key2", val2).Info("msg")`
11870
- **IMPORTANT: always use `pkg/logger`, never `log/slog` directly**
119-
120-
### CloudEvents Payloads
121-
`message_data` config uses CEL expressions, not static values:
122-
```yaml
123-
message_data:
124-
id: resource.id
125-
kind: resource.kind
126-
href: resource.href
127-
```
128-
CEL context:
129-
- `resource` — cluster/nodepool object from API (id, kind, href, generation, status, labels, etc.)
130-
- `reason` — decision reason string from engine (e.g., `"message decision matched"`, `"message decision result is false"`)
131-
- `condition("Type")` — custom function to look up resource status condition by type name
132-
- `now` — current timestamp
133-
- `timestamp()`, `duration()` — standard CEL time functions
71+
- Interface: `logger.HyperFleetLogger` with `Info()`, `Error()`, `Warn()`, `Debug()`, `V(level)`, `Extra()`
72+
- Chaining: `logger.Extra("key", val).Extra("key2", val2).Info("msg")`
13473

13574
### Testing
136-
- Table-driven tests with plain `if` assertions — no testify
137-
- Mocking via simple interface implementations (e.g., MockPublisher), no gomock
75+
- Table-driven tests with plain `if` assertions — no testify, no gomock
13876
- Unit tests live alongside code: `foo_test.go` next to `foo.go`
13977
- Integration tests in `test/integration/` with `//go:build integration` tag
14078
- Prometheus metrics verified with `prometheus/testutil`
141-
- Run single test: `go test -run TestDecisionEngine ./internal/engine/...`
142-
143-
## Git Workflow
14479

145-
- Branch from `main`, PR back to `main`
146-
- Branch naming: `HYPERFLEET-###-short-description`
147-
- Pre-commit hooks: run `make install-hooks` to install — enforces commit message format (`hyperfleet-commitlint`), Go formatting, linting, and vet
80+
## Boundaries
14881

149-
## Project Boundaries
82+
### DON'T
15083

151-
**DO NOT**:
15284
- Add business logic to Sentinel — orchestration decisions only, execution belongs in adapters
15385
- Store state in Sentinel — it is stateless, API is source of truth
15486
- Hardcode the resource polling interval — always use `poll_interval` from config for the main sentinel loop; adding a second resource polling loop bypasses the single-ticker backpressure model
15587

156-
**DO**:
88+
### DO
89+
15790
- Update `hyperfleet-api-spec` version in `go.mod` and run `make generate` when API spec changes
15891
- New exported functions require unit tests; new broker/API interactions require integration tests
15992
- Add metrics when adding observable behavior — see [docs/metrics.md](docs/metrics.md) for conventions

0 commit comments

Comments
 (0)