From 7e0590ca66a0c0ab0924e8a7b6dc106189d0bf31 Mon Sep 17 00:00:00 2001 From: amcheste-ai-agent <278991699+amcheste-ai-agent@users.noreply.github.com> Date: Mon, 11 May 2026 18:14:11 -0400 Subject: [PATCH 1/3] chore(brand): table-cell em-dash sweep + scorecard fixes Second pass following PR #224. Three small things: 1. Em-dash sweep in table cells (12 occurrences across 9 files). PR #224's mechanical sweep protected lines starting with `|` as code structure, but table cells contain rendered prose and the voice rule applies. Each em-dash replaced contextually: period-and-capitalize, comma, or word-rewrite. The one remaining em-dash in CONTRIBUTING.md:198 is inside a Go ```go code block (a kubebuilder marker comment example), correctly preserved. 2. scorecard.yml: publish_results now uses `github.ref_name == github.event.repository.default_branch` instead of hardcoded `refs/heads/main`. Same fix as engineering-handbook PR #16 and repo-template PR #11. The default here is `main`, so no behavior change today, but the workflow is now correct regardless of which branch is set as default (consistent with the family). 3. scorecard.yml: github/codeql-action/upload-sarif SHA pin replaced. The old pin (d4b3ca9fa7f69d38bfcd667bdc45bc373d16277e) is an imposter commit per OSSF Scorecard's anti-supply-chain check, which is why every Scorecard run since at least 2026-04-29 has failed with `error sending scorecard results to webapp: ... imposter commit ... does not belong to github/codeql-action/upload-sarif`. New pin (68bde559dea0fdcac2102bfdf6230c5f70eb485e) is the real v4 tag commit, verified via gh api. The push trigger also now fires on `develop` in addition to `main`, matching the family pattern. publish_results gating keeps the public score canonical to default-branch state. No-Linear-Issue: brand-alignment follow-up to PR #224 Co-Authored-By: Claude Opus 4.7 (1M context) Co-Authored-By: amcheste <13696614+amcheste@users.noreply.github.com> --- .github/workflows/scorecard.yml | 6 +++--- ARCHITECTURE.md | 2 +- README.md | 6 +++--- SECURITY.md | 2 +- docs/explanation/resources.md | 2 +- docs/helm-values.md | 2 +- docs/how-to/install/aks.md | 4 ++-- docs/how-to/operate/shared-storage.md | 2 +- docs/reference/api/index.md | 2 +- docs/tutorials/getting-started.md | 2 +- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 3716ce2..54bcfb7 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -5,7 +5,7 @@ on: schedule: - cron: '30 1 * * 1' # Every Monday at 01:30 UTC push: - branches: [main] + branches: [main, develop] workflow_dispatch: permissions: read-all @@ -28,7 +28,7 @@ jobs: with: results_file: results.sarif results_format: sarif - publish_results: ${{ github.ref == 'refs/heads/main' }} + publish_results: ${{ github.ref_name == github.event.repository.default_branch }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: @@ -36,6 +36,6 @@ jobs: path: results.sarif retention-days: 5 - - uses: github/codeql-action/upload-sarif@d4b3ca9fa7f69d38bfcd667bdc45bc373d16277e # v4 + - uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 with: sarif_file: results.sarif diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index db18a59..5dce9d5 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -104,7 +104,7 @@ The operator itself has no opinion about the CSI driver. It asks for a PVC with | Platform | Driver | Notes | |----------|--------|-------| | Kind (multi-node dev) | `nfs-ganesha/nfs-server-provisioner` | Installed by `hack/kind-setup.sh` as StorageClass `nfs`. Real RWX over an in-cluster NFS server. | -| Kind (single-node acceptance) | `rancher.io/local-path` under the `nfs` StorageClass alias | Installed by `hack/acceptance-setup.sh`. See "Single-node fallback" — not true RWX. | +| Kind (single-node acceptance) | `rancher.io/local-path` under the `nfs` StorageClass alias | Installed by `hack/acceptance-setup.sh`. See "Single-node fallback"; not true RWX. | | Amazon EKS | [EFS CSI driver](https://github.com/kubernetes-sigs/aws-efs-csi-driver) | StorageClass pointing at an EFS file system. RWX natively. | | Google GKE | [Filestore CSI driver](https://cloud.google.com/filestore/docs/csi-driver) | Enable the Filestore CSI add-on; Filestore instances advertise RWX. | | Azure AKS | [Azure Files CSI driver](https://learn.microsoft.com/azure/aks/azure-files-csi) | SMB or NFS-protocol file shares; both support RWX. | diff --git a/README.md b/README.md index d6db3f3..982b5e0 100644 --- a/README.md +++ b/README.md @@ -298,12 +298,12 @@ This README is the entry point. For deeper dives, every topic lives in a dedicat | Document | Read when you want to… | |----------|-----------------------| -| [ARCHITECTURE.md](ARCHITECTURE.md) | Understand how the operator models Agent Teams — phase state machine, PVC layout, RWX storage backends, coordination protocol, key design tradeoffs. | +| [ARCHITECTURE.md](ARCHITECTURE.md) | Understand how the operator models Agent Teams. Phase state machine, PVC layout, RWX storage backends, coordination protocol, key design tradeoffs. | | [TESTING.md](TESTING.md) | See the test strategy (unit / integration / acceptance / E2E), how to run each suite, and what each one actually verifies. | | [CONTRIBUTING.md](CONTRIBUTING.md) | Set up a dev environment, run the full build/test loop, follow the branch + PR workflow, and walk through "How to add a new reconciler feature." | -| [docs/helm-values.md](docs/helm-values.md) | Tune the Helm chart — every value documented with defaults and production override recipes. | +| [docs/helm-values.md](docs/helm-values.md) | Tune the Helm chart. Every value documented with defaults and production override recipes. | | [SECURITY.md](SECURITY.md) | Report a vulnerability or review the project's security policy. | -| [KUBECON.md](KUBECON.md) | See the talk framing and "interesting problems" log — useful context for why specific architectural choices were made. | +| [KUBECON.md](KUBECON.md) | See the talk framing and "interesting problems" log. Useful context for why specific architectural choices were made. | ## Development diff --git a/SECURITY.md b/SECURITY.md index 96690f6..49cb413 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,7 +7,7 @@ Only the latest released version is actively maintained. Security fixes are issu | Version | Supported | |---------|:---------:| | Latest release | ✅ | -| Older releases | ❌ — please upgrade | +| Older releases | ❌ please upgrade | The latest release is the most recent `v*` tag on https://github.com/amcheste/claude-teams-operator/releases. diff --git a/docs/explanation/resources.md b/docs/explanation/resources.md index 97d5c40..873be1b 100644 --- a/docs/explanation/resources.md +++ b/docs/explanation/resources.md @@ -4,7 +4,7 @@ kagents manages three custom resources. Most users only ever touch the first one | CRD | What it represents | When to use | |-----|-------------------|-------------| -| `AgentTeam` | A specific team running a specific job | One-off work — refactor, code review, report draft | +| `AgentTeam` | A specific team running a specific job | One-off work, e.g. refactor, code review, report draft | | `AgentTeamTemplate` | A reusable team blueprint | You'll instantiate the same team shape against many inputs | | `AgentTeamRun` | One instantiation of a template | Used together with `AgentTeamTemplate` | diff --git a/docs/helm-values.md b/docs/helm-values.md index 793e1cf..b160b1a 100644 --- a/docs/helm-values.md +++ b/docs/helm-values.md @@ -86,7 +86,7 @@ Defaults applied to PVCs the operator creates per AgentTeam. **Required:** the s | `metrics.serviceMonitor.enabled` | `false` | **Production:** set to `true` when running with kube-prometheus-stack. Requires the `monitoring.coreos.com` CRDs. | | `metrics.serviceMonitor.namespace` | `""` | Namespace for the ServiceMonitor. Defaults to the release namespace. Set this to the Prometheus namespace when using a namespace-scoped selector. | | `metrics.serviceMonitor.interval` | `30s` | Prometheus scrape interval. | -| `metrics.serviceMonitor.additionalLabels` | `{}` | Extra labels on the ServiceMonitor. Match your Prometheus CR's selector — e.g. `{release: kube-prometheus-stack}`. | +| `metrics.serviceMonitor.additionalLabels` | `{}` | Extra labels on the ServiceMonitor. Match your Prometheus CR's selector, e.g. `{release: kube-prometheus-stack}`. | ## Metrics. Grafana dashboard diff --git a/docs/how-to/install/aks.md b/docs/how-to/install/aks.md index 10a0c7e..f6509ec 100644 --- a/docs/how-to/install/aks.md +++ b/docs/how-to/install/aks.md @@ -30,8 +30,8 @@ Azure Files supports two protocols, and only one is suitable for kagents: | Protocol | RWX? | Use? | |----------|------|------| -| **NFS v4.1** | ✅ Yes | **Yes — use this.** | -| **SMB** | ⚠️ Partial | No — POSIX semantics on the agent's mailbox writes don't work reliably. | +| **NFS v4.1** | ✅ Yes | **Yes, use this.** | +| **SMB** | ⚠️ Partial | No. POSIX semantics on the agent's mailbox writes don't work reliably. | NFS shares require a Premium storage account (FileStorage SKU). The good news is Premium pricing is reasonable for the small share sizes kagents needs. diff --git a/docs/how-to/operate/shared-storage.md b/docs/how-to/operate/shared-storage.md index 038b403..29f8d68 100644 --- a/docs/how-to/operate/shared-storage.md +++ b/docs/how-to/operate/shared-storage.md @@ -10,7 +10,7 @@ The chart's default sizes are conservative; raise them if your teams handle larg | Volume | Default Helm value | Default size | When to raise | |--------|-------------------:|-------------:|---------------| -| Team state (mailboxes + tasks) | `storage.teamStateSize` | `5Gi` | Almost never — mailbox JSON is tiny. 5 GiB holds thousands of messages. | +| Team state (mailboxes + tasks) | `storage.teamStateSize` | `5Gi` | Almost never. Mailbox JSON is tiny. 5 GiB holds thousands of messages. | | Repo (coding mode) | `storage.repoSize` | `20Gi` | If your monorepo + per-teammate worktrees together exceed 20 GiB. Each worktree is roughly the size of your `git checkout`. For a 5-teammate team on a 4 GiB repo, 20 GiB might tip over. | | Output (Cowork mode) | `spec.workspace.output.size` (per-team) | n/a | Set per AgentTeam based on expected artifact volume. 1 GiB is fine for documents; raise for image/video output. | diff --git a/docs/reference/api/index.md b/docs/reference/api/index.md index f6ad1b4..f9af454 100644 --- a/docs/reference/api/index.md +++ b/docs/reference/api/index.md @@ -321,7 +321,7 @@ _Appears in:_ | `onComplete` _string_ | OnComplete determines what happens when the team finishes. | notify | Enum: [create-pr push-branch notify none]
| | `pullRequest` _[PullRequestSpec](#pullrequestspec)_ | PullRequest configures PR creation when onComplete is "create-pr". | | Optional: \{\}
| | `approvalGates` _[ApprovalGateSpec](#approvalgatespec) array_ | ApprovalGates pause execution before specified events until human approval is recorded.
Grant approval by annotating the AgentTeam: kubectl annotate agentteam approved.claude.amcheste.io/=true | | Optional: \{\}
| -| `maxRestarts` _integer_ | MaxRestarts bounds how many times each teammate pod may be re-spawned
after a Failed phase before the team itself is marked Failed. The lead
pod is not subject to this limit — a lead crash always fails the team. | 3 | Minimum: 0
Optional: \{\}
| +| `maxRestarts` _integer_ | MaxRestarts bounds how many times each teammate pod may be re-spawned
after a Failed phase before the team itself is marked Failed. The lead
pod is not subject to this limit; a lead crash always fails the team. | 3 | Minimum: 0
Optional: \{\}
| | `githubTokenSecret` _string_ | GitHubTokenSecret names a Secret in the team's namespace carrying a
GitHub token under the key GITHUB_TOKEN. Used by OnComplete=create-pr
(and OnComplete=push-branch, once implemented) to authenticate against
the GitHub REST API. | | Optional: \{\}
| | `prTitleTemplate` _string_ | PRTitleTemplate overrides the title template used by OnComplete=create-pr.
Available variables: .TeamName, .Namespace. When empty, falls back to
Spec.Lifecycle.PullRequest.TitleTemplate, then to the default
"claude-teams: \{\{.TeamName\}\}". | | Optional: \{\}
| | `gitCredentialsSecret` _string_ | GitCredentialsSecret names a Secret in the team's namespace carrying git
push credentials. The Secret must contain either 'ssh-privatekey' or
'token'. Used by OnComplete=push-branch (and OnComplete=create-pr when
push-branch runs ahead of it). Falls back to Spec.Repository.CredentialsSecret
when unset, so teams that already configured clone credentials with push
scope don't need to duplicate. | | Optional: \{\}
| diff --git a/docs/tutorials/getting-started.md b/docs/tutorials/getting-started.md index 6d89051..b0e533d 100644 --- a/docs/tutorials/getting-started.md +++ b/docs/tutorials/getting-started.md @@ -16,7 +16,7 @@ You don't need any cloud accounts or external services. Everything runs on your | [kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation) | 0.25+ | Single-node Kubernetes for dev | | [kubectl](https://kubernetes.io/docs/tasks/tools/) | 1.28+ | Interact with the cluster | | [helm](https://helm.sh/docs/intro/install/) | 3.14+ | Install the operator chart | -| [Anthropic API key](https://console.anthropic.com/) | — | Required for agents to actually call Claude | +| [Anthropic API key](https://console.anthropic.com/) | (any) | Required for agents to actually call Claude | You'll also need the kagents repo cloned locally so you can use the included `make kind-create` setup script (which provisions a Kind cluster with the NFS-style RWX storage the operator needs): From 9e8e36c0ec33716e2d16100a6660f77e9e9b0812 Mon Sep 17 00:00:00 2001 From: amcheste-ai-agent <278991699+amcheste-ai-agent@users.noreply.github.com> Date: Mon, 11 May 2026 18:34:09 -0400 Subject: [PATCH 2/3] =?UTF-8?q?chore(brand):=20em-dash=20sweep=20=E2=80=94?= =?UTF-8?q?=20sync=20MaxRestarts=20doc=20comment=20to=20source?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #228 changed the regenerated docs/reference/api/index.md to swap an em-dash for a semicolon in the MaxRestarts description, but missed the matching Go doc comment in api/v1alpha1/agentteam_types.go. The `make docs-api` regeneration step in CI then pulled the em-dash back from source and the Lint job's diff check failed. Sync the source comment to match the rendered docs. Co-Authored-By: Claude Opus 4.7 (1M context) Co-Authored-By: amcheste <13696614+amcheste@users.noreply.github.com> --- api/v1alpha1/agentteam_types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v1alpha1/agentteam_types.go b/api/v1alpha1/agentteam_types.go index f3b4804..ec86c6c 100644 --- a/api/v1alpha1/agentteam_types.go +++ b/api/v1alpha1/agentteam_types.go @@ -306,7 +306,7 @@ type LifecycleSpec struct { // MaxRestarts bounds how many times each teammate pod may be re-spawned // after a Failed phase before the team itself is marked Failed. The lead - // pod is not subject to this limit — a lead crash always fails the team. + // pod is not subject to this limit; a lead crash always fails the team. // +kubebuilder:default=3 // +kubebuilder:validation:Minimum=0 // +optional From d1810e4a76c01ee71d50f68dc5bec129adbe635d Mon Sep 17 00:00:00 2001 From: amcheste-ai-agent <278991699+amcheste-ai-agent@users.noreply.github.com> Date: Mon, 11 May 2026 18:37:36 -0400 Subject: [PATCH 3/3] chore(brand): regenerate CRD manifests for em-dash sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `make manifests` regenerates the CRD YAMLs from the Go type descriptions, so the MaxRestarts comment change also has to be reflected in: - charts/claude-teams-operator/crds/claude.amcheste.io_agentteams.yaml - charts/claude-teams-operator/crds/claude.amcheste.io_agentteamruns.yaml - charts/claude-teams-operator/crds/claude.amcheste.io_agentteamtemplates.yaml - config/crd/bases/claude.amcheste.io_agentteams.yaml - config/crd/bases/claude.amcheste.io_agentteamruns.yaml - config/crd/bases/claude.amcheste.io_agentteamtemplates.yaml Pure regeneration — no logic change. Co-Authored-By: Claude Opus 4.7 (1M context) Co-Authored-By: amcheste <13696614+amcheste@users.noreply.github.com> --- .../crds/claude.amcheste.io_agentteamruns.yaml | 2 +- .../crds/claude.amcheste.io_agentteams.yaml | 2 +- .../crds/claude.amcheste.io_agentteamtemplates.yaml | 2 +- config/crd/bases/claude.amcheste.io_agentteamruns.yaml | 2 +- config/crd/bases/claude.amcheste.io_agentteams.yaml | 2 +- config/crd/bases/claude.amcheste.io_agentteamtemplates.yaml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/charts/claude-teams-operator/crds/claude.amcheste.io_agentteamruns.yaml b/charts/claude-teams-operator/crds/claude.amcheste.io_agentteamruns.yaml index 0d574a7..62c1c6e 100644 --- a/charts/claude-teams-operator/crds/claude.amcheste.io_agentteamruns.yaml +++ b/charts/claude-teams-operator/crds/claude.amcheste.io_agentteamruns.yaml @@ -262,7 +262,7 @@ spec: description: |- MaxRestarts bounds how many times each teammate pod may be re-spawned after a Failed phase before the team itself is marked Failed. The lead - pod is not subject to this limit — a lead crash always fails the team. + pod is not subject to this limit; a lead crash always fails the team. format: int32 minimum: 0 type: integer diff --git a/charts/claude-teams-operator/crds/claude.amcheste.io_agentteams.yaml b/charts/claude-teams-operator/crds/claude.amcheste.io_agentteams.yaml index 72acd2a..13f07a8 100644 --- a/charts/claude-teams-operator/crds/claude.amcheste.io_agentteams.yaml +++ b/charts/claude-teams-operator/crds/claude.amcheste.io_agentteams.yaml @@ -307,7 +307,7 @@ spec: description: |- MaxRestarts bounds how many times each teammate pod may be re-spawned after a Failed phase before the team itself is marked Failed. The lead - pod is not subject to this limit — a lead crash always fails the team. + pod is not subject to this limit; a lead crash always fails the team. format: int32 minimum: 0 type: integer diff --git a/charts/claude-teams-operator/crds/claude.amcheste.io_agentteamtemplates.yaml b/charts/claude-teams-operator/crds/claude.amcheste.io_agentteamtemplates.yaml index c0135fb..a9ff55d 100644 --- a/charts/claude-teams-operator/crds/claude.amcheste.io_agentteamtemplates.yaml +++ b/charts/claude-teams-operator/crds/claude.amcheste.io_agentteamtemplates.yaml @@ -155,7 +155,7 @@ spec: description: |- MaxRestarts bounds how many times each teammate pod may be re-spawned after a Failed phase before the team itself is marked Failed. The lead - pod is not subject to this limit — a lead crash always fails the team. + pod is not subject to this limit; a lead crash always fails the team. format: int32 minimum: 0 type: integer diff --git a/config/crd/bases/claude.amcheste.io_agentteamruns.yaml b/config/crd/bases/claude.amcheste.io_agentteamruns.yaml index 0d574a7..62c1c6e 100644 --- a/config/crd/bases/claude.amcheste.io_agentteamruns.yaml +++ b/config/crd/bases/claude.amcheste.io_agentteamruns.yaml @@ -262,7 +262,7 @@ spec: description: |- MaxRestarts bounds how many times each teammate pod may be re-spawned after a Failed phase before the team itself is marked Failed. The lead - pod is not subject to this limit — a lead crash always fails the team. + pod is not subject to this limit; a lead crash always fails the team. format: int32 minimum: 0 type: integer diff --git a/config/crd/bases/claude.amcheste.io_agentteams.yaml b/config/crd/bases/claude.amcheste.io_agentteams.yaml index 72acd2a..13f07a8 100644 --- a/config/crd/bases/claude.amcheste.io_agentteams.yaml +++ b/config/crd/bases/claude.amcheste.io_agentteams.yaml @@ -307,7 +307,7 @@ spec: description: |- MaxRestarts bounds how many times each teammate pod may be re-spawned after a Failed phase before the team itself is marked Failed. The lead - pod is not subject to this limit — a lead crash always fails the team. + pod is not subject to this limit; a lead crash always fails the team. format: int32 minimum: 0 type: integer diff --git a/config/crd/bases/claude.amcheste.io_agentteamtemplates.yaml b/config/crd/bases/claude.amcheste.io_agentteamtemplates.yaml index c0135fb..a9ff55d 100644 --- a/config/crd/bases/claude.amcheste.io_agentteamtemplates.yaml +++ b/config/crd/bases/claude.amcheste.io_agentteamtemplates.yaml @@ -155,7 +155,7 @@ spec: description: |- MaxRestarts bounds how many times each teammate pod may be re-spawned after a Failed phase before the team itself is marked Failed. The lead - pod is not subject to this limit — a lead crash always fails the team. + pod is not subject to this limit; a lead crash always fails the team. format: int32 minimum: 0 type: integer