## What this PR does Adds the `triage/needs-proposal` label to `.github/labels.yml` for feature requests that need a design proposal in [cozystack/community](https://github.com/cozystack/community) before any work starts here. Until now that routing rule lived only in chat, so such requests kept landing in this repository and were re-filed by hand with nothing on the issue saying why. AGENTS.md now spells out the handling next to the rest of the triage guidance: the request is re-filed in cozystack/community, closed here with the label and a link to the proposal, and work in this repository starts from a new issue once the proposal is accepted. ### Screenshots Not applicable, no UI change. ### Downstream repositories - [x] No downstream repository is affected by this change - [ ] [cozystack/website](https://github.com/cozystack/website) - follow-up: - [ ] [cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack) - follow-up: - [ ] [cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack) - follow-up: - [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up: - [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up: - [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) - follow-up: - [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) - follow-up: - [ ] [cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server) - follow-up: - [ ] [cozystack/external-apps-example](https://github.com/cozystack/external-apps-example) - follow-up: - [ ] [cozystack/examples](https://github.com/cozystack/examples) - follow-up: The diff touches `.github/labels.yml` and `AGENTS.md` only; neither file appears in the downstream trigger map in `docs/agents/contributing.md`. ### Release note ```release-note chore(labels): add triage/needs-proposal for feature requests that need a design proposal in cozystack/community before work starts here ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Chores** - Added a new triage label for issues that require a design proposal before implementation. - Documented the process for submitting, reviewing, and accepting feature proposals before work begins. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
9.9 KiB
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 - Action: Read the entire file and follow ALL instructions step-by-step
- Read:
-
Changelog generation (e.g., "generate changelog", "create changelog", "prepare changelog for version X")
- Read:
changelog.md - Action: Read the entire file and follow ALL steps in the checklist. Do NOT skip any mandatory steps
- Read:
-
Release creation (e.g., "create release", "prepare release", "tag release", "make a release")
- Read:
releasing.md - Action: Read the file and follow the referenced release process in
docs/release.md
- Read:
-
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 - 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.shis the enumeration shared by the promote, retag, mirror and candidate-verify tooling — extend it there rather than teaching an individual script a new path. The one exception ishack/overlay-main-images.sh, which reads refs but walks the tree itself, so a newly declared file does not reach it;hack/promote-packages-artifact.shsources nothing because it publishes the whole tree and consumes no refs at all — the doc carries both cases
- Read:
-
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 - Action: Read relevant sections to understand project structure and conventions
- Read:
-
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 - 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-levelEXIT/RETURNtraps (a self-contained one inside a Chainsawscriptstep or an explicit subshell is fine — see the doc), fail-fast on HelmRelease readiness
- Read:
-
General questions about contributing
- Read:
contributing.md - Action: Read the file to understand git workflow, commit format, PR process
- Read:
-
Issue and PR labeling, triage (e.g., "label this issue", "what label should I use", "triage this", "categorize")
- Read:
.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.yamllabels 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 onlytriage/*label an issue has and the next sweep puts one back - A feature request that needs design first gets
triage/needs-proposal, is re-filed in cozystack/community as an issue or a design-proposal PR, and is closed here with a link to it (re-file rather than transfer, so the label stays on the closed issue as the record); work in this repository starts only once that proposal is accepted, from a new issue that references it - For
area/*: accuracy outweighs reuse. If no existingarea/*truly fits the change, propose a new one via PR (extend.github/labels.ymland the scope mapping in.github/workflows/pr-labeler.yaml) — do not shoehorn the change into a wrong area.area/uncategorizedis 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 fromcontributing.md) auto-applieskind/*andarea/*via.github/workflows/pr-labeler.yaml. Append!(or add aBREAKING CHANGE:footer) to applykind/breaking-change
- Read:
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.mdcan 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 catalogpackages/extra/- Tenant-specific modulescmd/,internal/,pkg/- Go codeapi/- 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; an agent-assisted commit adds oneAssisted-by: LLMtrailer - Comments and commit bodies: WHY, not a narration of WHAT; see Review Blockers in contributing.md
- Prose: One continuous line per paragraph — see Prose Formatting
What NOT to Do
- ❌ Edit
/vendor/,zz_generated.*.go, upstream charts directly - ❌ Modify
go.mod/go.summanually (usego get) - ❌ Force push to main/master
- ❌ Commit built artifacts from
_out - ❌ Credit an AI model or its vendor by name in a commit trailer or in an authorship line in a PR description or comment, or put a
Claude-Session:trailer or a session URL into any of them - ❌ 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.