mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-03 10:37:21 +09:00
Issues created via the API or gh bypass the issue templates and arrive without any triage/* label; 252 of the 396 open issues carry none. Label issues on arrival (opened/reopened) and run a daily sweep as a backstop: issues already prioritised, assigned, or marked as epics get triage/accepted, the rest triage/needs-triage. A signal has to be on stale.yaml's exempt-issue-labels, because triage/accepted is itself exempt and a signal that is not would grant a permanent stale reprieve as a side effect of being labeled. That is necessary and not sufficient: lifecycle/frozen is exempt and still not a signal, because a lifecycle/* label says what the stale bot may do with an issue and nothing about whether anybody reviewed it. The sweep paces its writes and caps how many it makes per run, so a pass over a large backlog stays inside GitHub's secondary rate limits instead of failing partway through. Each run writes a job summary with the counts, the issue numbers per label, and both remainders it can leave behind, because a backlog pass logs a line per issue and nobody reads 252 of those to find out what happened. The manual dispatch defaults to dry-run, so the one entry point a human can reach writes nothing until somebody unchecks the box. The schedule is the one event that writes without being asked. Deleting a triage label does not undo a decision: an issue left with none is relabeled by the next sweep, so AGENTS.md's labeling section says to change a decision by replacing the label instead. No PR lane can exercise this workflow, so the first real run is a sweep over every open issue. A contract test pins the executable lines that bound that: the pull-request skip, the already-triaged skip, the pacing and the cap, the dry-run default, the pinned action, the token scopes, that no signal comes from the lifecycle/* namespace, and that the summary is written with the await that makes it flush. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la>
93 lines
8.9 KiB
Markdown
93 lines
8.9 KiB
Markdown
# AI Agents Overview
|
|
|
|
This file provides structured guidance for AI coding assistants and agents working with the **Cozystack** project.
|
|
|
|
## Activation
|
|
|
|
**CRITICAL**: When the user asks you to do something that matches the scope of a documented process, you MUST read the corresponding documentation file and follow the instructions exactly as written.
|
|
|
|
- **Commits, PRs, git operations** (e.g., "create a commit", "make a PR", "fix review comments", "rebase", "cherry-pick")
|
|
- Read: [`contributing.md`](./docs/agents/contributing.md)
|
|
- Action: Read the entire file and follow ALL instructions step-by-step
|
|
|
|
- **Changelog generation** (e.g., "generate changelog", "create changelog", "prepare changelog for version X")
|
|
- Read: [`changelog.md`](./docs/agents/changelog.md)
|
|
- Action: Read the entire file and follow ALL steps in the checklist. Do NOT skip any mandatory steps
|
|
|
|
- **Release creation** (e.g., "create release", "prepare release", "tag release", "make a release")
|
|
- Read: [`releasing.md`](./docs/agents/releasing.md)
|
|
- Action: Read the file and follow the referenced release process in `docs/release.md`
|
|
|
|
- **Image references, tags and digests** (e.g., "why is this image tagged rc", "add an image to a package", "change how an image is stamped", "promotion/nightly missed an image", "where do image refs live")
|
|
- Read: [`image-refs.md`](./docs/agents/image-refs.md)
|
|
- Action: Read the entire file. Image refs live in three storage shapes and carry three classes of tag; a tool that knows only one shape skips images silently rather than failing. `hack/lib/image-refs.sh` is the enumeration shared by the promote, retag and mirror tooling — extend it there rather than teaching an individual script a new path. Note `hack/overlay-main-images.sh` is a fourth consumer that still walks the tree itself and does not source the library
|
|
|
|
- **Project structure, conventions, code layout** (e.g., "where should I put X", "what's the convention for Y", "how is the project organized")
|
|
- Read: [`overview.md`](./docs/agents/overview.md)
|
|
- Action: Read relevant sections to understand project structure and conventions
|
|
|
|
- **E2E tests and E2E CI** (e.g., "write/fix an e2e test", "stabilize a flaky test", "add a bats test", "change the e2e workflow", "why did e2e fail")
|
|
- Read: [`e2e-testing.md`](./docs/agents/e2e-testing.md)
|
|
- Action: Read the entire file and follow the conventions exactly — no new retries on deterministic steps, event-driven backstops before every `kubectl wait`, no test-level `EXIT`/`RETURN` traps (a self-contained one inside a Chainsaw `script` step or an explicit subshell is fine — see the doc), fail-fast on HelmRelease readiness
|
|
|
|
- **General questions about contributing**
|
|
- Read: [`contributing.md`](./docs/agents/contributing.md)
|
|
- Action: Read the file to understand git workflow, commit format, PR process
|
|
|
|
- **Issue and PR labeling, triage** (e.g., "label this issue", "what label should I use", "triage this", "categorize")
|
|
- Read: [`.github/labels.yml`](./.github/labels.yml)
|
|
- Action: Use labels defined there. Conventions follow the Kubernetes scheme — `kind/*` (type), `area/*` (subsystem), `priority/*` (urgency), `triage/*` (review state), `lifecycle/*` (auto-close), `do-not-merge/*` (PR blockers), `security/*` (severity)
|
|
- For `triage/*`: `.github/workflows/issue-triage.yaml` labels an issue on arrival and sweeps daily for any open issue carrying none, so change a triage decision by replacing the label rather than removing it — remove the only `triage/*` label an issue has and the next sweep puts one back
|
|
- For `area/*`: accuracy outweighs reuse. If no existing `area/*` truly fits the change, propose a new one via PR (extend `.github/labels.yml` and the scope mapping in `.github/workflows/pr-labeler.yaml`) — do not shoehorn the change into a wrong area. `area/uncategorized` is the auto-labeler fallback; treat it as a signal to pick a fit, create a new area, or correct the PR title
|
|
- PR titles: a Conventional Commits header (`type(scope): description`, types from [`contributing.md`](./docs/agents/contributing.md)) auto-applies `kind/*` and `area/*` via `.github/workflows/pr-labeler.yaml`. Append `!` (or add a `BREAKING CHANGE:` footer) to apply `kind/breaking-change`
|
|
|
|
**Important rules:**
|
|
- ✅ **ONLY read the file if the task matches the documented process scope** - do not read files for tasks that don't match their purpose
|
|
- ✅ **ALWAYS read the file FIRST** before starting the task (when applicable)
|
|
- ✅ **Follow instructions EXACTLY** as written in the documentation
|
|
- ✅ **Do NOT skip mandatory steps** (especially in changelog.md)
|
|
- ✅ **Do NOT assume** you know the process - always check the documentation when the task matches
|
|
- ❌ **Do NOT read files** for tasks that are outside their documented scope
|
|
- 📖 **Note**: [`overview.md`](./docs/agents/overview.md) can be useful as a reference to understand project structure and conventions, even when not explicitly required by the task
|
|
|
|
## Project Overview
|
|
|
|
**Cozystack** is a Kubernetes-based platform for building cloud infrastructure with managed services (databases, VMs, K8s clusters), multi-tenancy, and GitOps delivery.
|
|
|
|
## Quick Reference
|
|
|
|
### Code Structure
|
|
- `packages/core/` - Core platform charts (installer, platform)
|
|
- `packages/system/` - System components (CSI, CNI, operators)
|
|
- `packages/apps/` - User-facing applications in catalog
|
|
- `packages/extra/` - Tenant-specific modules
|
|
- `cmd/`, `internal/`, `pkg/` - Go code
|
|
- `api/` - Kubernetes CRDs
|
|
|
|
### Conventions
|
|
- **Helm Charts**: Umbrella pattern, vendored upstream charts in `charts/`
|
|
- **Go Code**: Controller-runtime patterns, kubebuilder style
|
|
- **Git Commits**: Conventional Commits (`type(scope): description`) with `--signoff`
|
|
- **Prose**: One continuous line per paragraph — see [Prose Formatting](#prose-formatting)
|
|
|
|
### What NOT to Do
|
|
- ❌ Edit `/vendor/`, `zz_generated.*.go`, upstream charts directly
|
|
- ❌ Modify `go.mod`/`go.sum` manually (use `go get`)
|
|
- ❌ Force push to main/master
|
|
- ❌ Commit built artifacts from `_out`
|
|
- ❌ Hardwrap a prose paragraph in markdown, a PR body, or an issue comment
|
|
|
|
## Prose Formatting
|
|
|
|
Markdown files and everything an agent publishes to GitHub — PR bodies, issue bodies, review comments, release notes — use **one continuous line per paragraph**. Renderers collapse a soft line break into a space, so a paragraph hardwrapped at ~80 columns renders exactly like the same paragraph on one line, while breaking narrow viewports, mangling nested list and table rendering, and turning a one-word edit into a diff that reflows the entire block. The renderer decides where the line ends; the author does not.
|
|
|
|
Line breaks stay wherever they carry meaning: code fences, one item per list line, tables, headings, blockquotes, front matter, and README badge stacks. The rule governs prose paragraphs and nothing else. Commit messages are the deliberate exception — `git log` and the tooling around it still expect a body wrapped at ~72 columns.
|
|
|
|
This is the rule LLM agents break most often, because an ~80-column wrap is correct in the places they spend most of their time (Go comments, commit bodies) and the reflex leaks from there into documentation and GitHub. Treat it as a mechanical check at the moment of writing, not as a style preference to weigh: before saving a markdown file or passing `--body` to `gh`, look at each paragraph and confirm it is a single line.
|
|
|
|
The rule applies to prose this repository owns, and to new or changed paragraphs. Much of the existing tree predates it and is wrapped throughout; that is not a defect to go and fix. Vendored upstream chart docs (`packages/*/*/charts/**`) must stay verbatim — `make update` regenerates them — and published changelogs are historical records. Neither is in scope.
|
|
|
|
`.claude/hooks/md-no-hardwrap.py` enforces the rule for agents that support PreToolUse hooks (registered for Claude Code in `.claude/settings.json`). It refuses a `Write`/`Edit`/`MultiEdit` that would *add* a hardwrapped paragraph, list item or blockquote to a markdown file, and a `gh` command that would publish one to GitHub. A break counts as added only when the edit wrote both lines it joins, so fixing a typo inside a paragraph that was already wrapped goes through, while rewriting the same file as fresh hardwrapped prose does not. Anything it cannot read with certainty it allows — a guard that blocks legitimate work gets switched off, and then it guards nothing — which includes a body the shell assembles at runtime, and a `--body-file` written by the very command being checked, since the file does not exist yet when the hook runs. `hack/md-no-hardwrap.bats` covers it under `make unit-tests` and requires `python3`. Agents on other harnesses are held to the same rule without the hook.
|
|
|
|
`.claude/settings.json` is tracked, so keep personal Claude Code overrides in `.claude/settings.local.json`, which is not. A personal `.claude/settings.json` predating this will be overwritten on pull without warning, because git had been ignoring it.
|