Skip to content

Commit a921754

Browse files
Merge pull request #9 from gitcommitankit/phase-6
Phase 6
2 parents 38551be + 442d908 commit a921754

42 files changed

Lines changed: 2585 additions & 408 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/AGENTS.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
- Comments on fields in `api/v1alpha1/` are parsed by `controller-gen` into CRD OpenAPI schema descriptions. Keep them user-facing and precise.
3838

3939
4. **Update Docs on Architecture Changes**:
40-
- When an architecture boundary or CRD field changes, update `docs/agentrax.md` and `.agents/skills/agentrax-context/SKILL.md` in the same commit.
40+
- When an architecture boundary or CRD field changes, update `docs/ARCHITECTURE.md` and `.agents/skills/agentrax-context/SKILL.md` in the same commit.
4141

4242
## Tooling & Developer Environment
4343

@@ -52,16 +52,17 @@ Configure your MCP client with `--project-from-cwd` (for example, `serena start-
5252

5353
**Use Serena tools instead of text search for the following tasks:**
5454

55-
| Task | Use instead of |
56-
| ---- | -------------- |
57-
| Find where a type, function, or constant is defined | `find_symbol` / `find_declaration` rather than `grep` |
58-
| Find all usages/call sites of a symbol across packages | `find_referencing_symbols` rather than `grep -r` |
59-
| Understand what symbols a file or package exports | `get_symbols_overview` rather than skimming the file |
60-
| Rename a symbol consistently across all packages | `rename_symbol` rather than manual multi-file sed |
61-
| Navigate to where an interface is implemented | `find_implementations` rather than text search |
62-
| Check diagnostics/type errors before proposing a fix | `get_diagnostics_for_file` |
55+
| Task | Use instead of |
56+
| ------------------------------------------------------ | ----------------------------------------------------- |
57+
| Find where a type, function, or constant is defined | `find_symbol` / `find_declaration` rather than `grep` |
58+
| Find all usages/call sites of a symbol across packages | `find_referencing_symbols` rather than `grep -r` |
59+
| Understand what symbols a file or package exports | `get_symbols_overview` rather than skimming the file |
60+
| Rename a symbol consistently across all packages | `rename_symbol` rather than manual multi-file sed |
61+
| Navigate to where an interface is implemented | `find_implementations` rather than text search |
62+
| Check diagnostics/type errors before proposing a fix | `get_diagnostics_for_file` |
6363

6464
**When NOT to use Serena:**
65+
6566
- Simple single-file reads — `view_file` is faster.
6667
- Writing or replacing file content — use the standard edit tools.
6768
- Searching for plain string literals (log messages, YAML values) — `grep` is fine.

.agents/skills/agentrax-context/SKILL.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ name: agentrax-context
33
description: Project context and settled architecture decisions for the Agentrax Kubernetes operator (module agentrax.io/v1alpha1, repo agentrax). Always consult this before writing, reviewing, or reasoning about any code in this repository — CRD types, the reconciler, the rollout controller, the autoscaler, the quota webhook, or the MCP registry — so implementation stays consistent with the design doc instead of drifting or re-deriving decisions that are already settled. Trigger on any mention of AgentDeployment, TenantQuota, canary rollout, or this repo's controllers, even if the user doesn't name the skill directly.
44
---
55

6-
> When uncertain about any architecture decision, defer to `docs/agentrax.md` rather than improvising. Don't guess when the doc has the answer.
6+
# Agentrax Context Skill
7+
8+
> When uncertain about any architecture decision, defer to `docs/ARCHITECTURE.md` rather than improvising. Don't guess when the doc has the answer.
79
810
## Non-negotiable terminology
911

@@ -23,22 +25,24 @@ description: Project context and settled architecture decisions for the Agentrax
2325

2426
## Package map
2527

26-
| Package | Responsibility |
27-
| ---------------------- | ----------------------------------------------------------------------------------------- |
28-
| `api/v1alpha1/` | CRD Go types, validation markers, defaulting. No business logic. |
29-
| `internal/controller/` | Reconcile loops. Only code that calls the Kubernetes API for core owned resources. |
30-
| `internal/rollout/` | Canary state machine and PromQL threshold evaluation. |
31-
| `internal/scaling/` | HPA generation and quota-capped scaling logic. |
32-
| `internal/registry/` | MCP registrar, registry HTTP handler, TTL sweep. |
33-
| `internal/quota/` | Quota arithmetic and in-flight reservation. Shared by webhook and TenantQuota reconciler. |
28+
| Package | Responsibility |
29+
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
30+
| `api/v1alpha1/` | CRD Go types, validation markers, defaulting. No business logic. |
31+
| `internal/controller/` | Reconcile loops. Only code that calls the Kubernetes API for core-owned resources. |
32+
| `internal/rollout/` | Canary state machine and PromQL threshold evaluation. |
33+
| `internal/scaling/` | HPA generation and quota-capped scaling logic. |
34+
| `internal/registry/` | MCP registrar, registry HTTP handler, TTL sweep. |
35+
| `internal/quota/` | Quota arithmetic and in-flight reservation. Shared by webhook and TenantQuota reconciler. |
3436
| `internal/webhook/` | Validating and mutating admission webhooks. Lives here (not `api/`) to import `internal/quota` without creating an import cycle. |
35-
| `internal/metrics/` | Shared Prometheus client plumbing used by rollout and scaling. |
37+
| `internal/metrics/` | Shared Prometheus client plumbing used by rollout and scaling. |
3638

3739
## Where the hard logic lives
3840

39-
- **`internal/rollout/`** — never evaluate `rollback` thresholds against a sample smaller than `minRequestSample`. A 10%-weight canary at low traffic produces statistically meaningless error rates; gate on sample size first.
41+
- **`internal/rollout/`** — never evaluate `rollback` thresholds against a sample smaller than `minRequestSample`. A 10%-weight canary at low traffic produces statistically meaningless error rates; gate on sample size first. Canary steps must include at least one terminal `setWeight: 100` step for full promotion. Range query windows must format to canonical Prometheus syntax (`5m`, `1h`, `30s`, no trailing `0s`).
4042
- **`internal/quota/`** — two concurrent near-limit creates can individually pass a read-then-write quota check but combined exceed it. Use an in-flight reservation (short-lived in-memory map, keyed by tenant), not a naive status read.
4143
- **`internal/registry/`** — registration requires a successful MCP-level `initialize` handshake, not just Kubernetes readiness. Entries carry a TTL/heartbeat; ungraceful termination (OOM-kill, node failure) skips the deletion event path entirely, so don't rely on it.
44+
- **`internal/metrics/`** — all Prometheus HTTP responses must be read with `io.LimitReader` (1 MiB ceiling) to protect against memory exhaustion.
45+
- **`internal/controller/`** — reconcilers consume MCP registry operations via the `AgentRegistrar` interface (`Register`, `Deregister`, `Heartbeat`) for test isolation without polluting production structs.
4246
- Finalizer ordering: deregister from MCP _before_ the `Service` is garbage collected. Controller-runtime's foreground deletion via finalizer is the enforcement mechanism, not best-effort.
4347
- Quota reduction: lowering `TenantQuota` below current usage sets an `OverQuota` condition and blocks new creates/scale-ups. Never forcibly delete existing resources.
4448

.coderabbit.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ reviews:
6565
- Finalizer constant must be `AgentDeploymentFinalizer` = `"agentrax.io/mcp-deregister"`.
6666
Never hardcode the string directly; always use the constant.
6767
- Validation markers (`+kubebuilder:validation:*`) on spec fields must
68-
match the rules in docs/agentrax.md section 6.3. Pay special attention
68+
match the rules in docs/ARCHITECTURE.md. Pay special attention
6969
to enum values for `spec.replicas.metric` and `spec.rollout.strategy`.
7070
7171
# Reconciler — enforce controller-runtime patterns strictly.
@@ -222,7 +222,7 @@ reviews:
222222
instructions: |
223223
- Any change to a CRD field, architecture boundary, or package
224224
responsibility must be reflected here in the same PR.
225-
- `docs/agentrax.md` is the source of truth for architecture decisions.
225+
- `docs/ARCHITECTURE.md` is the source of truth for architecture decisions.
226226
Flag any PR that changes architecture without updating it.
227227
228228
# ── Custom review instructions (global) ──────────────────────────────────

.github/workflows/ci.yml

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,27 @@ jobs:
4949
name: coverage
5050
path: cover.out
5151

52+
helm-lint:
53+
name: Helm Lint & Dry-run
54+
runs-on: ubuntu-latest
55+
steps:
56+
- uses: actions/checkout@v4
57+
58+
- name: Set up Helm
59+
uses: azure/setup-helm@v4
60+
with:
61+
version: v3.14.0
62+
63+
- name: Lint Helm Chart
64+
run: helm lint charts/agentrax/
65+
66+
- name: Template Helm Chart
67+
run: helm template test charts/agentrax/ --debug
68+
5269
build:
5370
name: Docker Build
5471
runs-on: ubuntu-latest
55-
needs: [lint, test]
72+
needs: [lint, test, helm-lint]
5673
steps:
5774
- uses: actions/checkout@v4
5875

@@ -71,3 +88,27 @@ jobs:
7188
tags: ghcr.io/gitcommitankit/agentrax:${{ github.sha }}
7289
cache-from: type=gha
7390
cache-to: type=gha,mode=max
91+
92+
e2e:
93+
name: End-to-End Tests (kind)
94+
runs-on: ubuntu-latest
95+
needs: [build]
96+
steps:
97+
- uses: actions/checkout@v4
98+
99+
- name: Set up Go
100+
uses: actions/setup-go@v5
101+
with:
102+
go-version: "1.23"
103+
cache: true
104+
105+
- name: Create kind Cluster
106+
uses: helm/kind-action@v1.10.0
107+
with:
108+
cluster_name: agentrax-e2e
109+
110+
- name: Install cluster dependencies
111+
run: make deploy-deps
112+
113+
- name: Run E2E Tests
114+
run: make test-e2e

.github/workflows/soak.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Autoscaling Soak Test
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
soak_duration_minutes:
7+
description: "Duration to run autoscaling soak in minutes"
8+
default: "10"
9+
required: false
10+
11+
jobs:
12+
soak:
13+
name: Autoscaling Soak Test (kind)
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
18+
- name: Set up Go
19+
uses: actions/setup-go@v5
20+
with:
21+
go-version: "1.23"
22+
cache: true
23+
24+
- name: Create kind cluster
25+
uses: helm/kind-action@v1.10.0
26+
with:
27+
cluster_name: agentrax-soak
28+
29+
- name: Install cluster dependencies
30+
run: make deploy-deps
31+
32+
- name: Run Autoscaling Soak Suite
33+
run: make test-e2e-soak
34+
env:
35+
SOAK_DURATION_MINUTES: ${{ github.event.inputs.soak_duration_minutes }}

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ test: manifests generate fmt vet envtest ## Run tests.
6868
test-e2e:
6969
go test ./test/e2e/ -v -ginkgo.v
7070

71+
.PHONY: test-e2e-soak
72+
test-e2e-soak: ## Run the long-running autoscaling soak test suite.
73+
go test ./test/e2e/... -tags e2e -v --timeout 25m -run TestE2E
74+
7175
.PHONY: lint
7276
lint: golangci-lint ## Run golangci-lint linter
7377
$(GOLANGCI_LINT) run

0 commit comments

Comments
 (0)