cozystack/docs/agents/contributing.md
Aleksei Sviridkin 4813566a30
docs(agents): mark scopes list as illustrative examples
Address review feedback from gemini-code-assist on docs/agents/contributing.md:11:
Scope linters kept flagging valid scopes like 'agents' as unknown because
the list read as exhaustive. Annotate it as examples (not exhaustive) and
add 'agents' to the Other group so both humans and review bots stop
tripping on scopes that are already in regular use across the repo
history.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-23 18:02:04 +03:00

5.2 KiB

Contributing Conventions for AI Agents

Project-side conventions for commits, branches, and pull requests in Cozystack.

Checklist for Creating a Pull Request

  • Commit message follows Conventional Commits format
  • Commit is signed off with --signoff
  • Branch is rebased on upstream/main (no extra commits)
  • PR body includes description and release note
  • Ran make generate in every package whose values.yaml, values.schema.json, Chart.yaml, or README.md was touched, and committed the regenerated files

Regenerate Artifacts Before Committing

Several files in each package are produced by make generate from values.yaml + values.schema.json and must stay in sync with the hand-edited sources:

  • packages/(apps|extra)/<name>/README.md — regenerated by cozyvalues-gen (parameter table, formatting).
  • packages/(apps|extra)/<name>/values.schema.jsoncozyvalues-gen rewrites ordering and derived fields.
  • packages/system/<name>-rd/cozyrds/<name>.yaml — produced by hack/update-crd.sh, which make generate invokes.

Before committing edits to any of those sources, run make generate inside the package and stage the full diff:

make -C packages/<apps-or-extra>/<name> generate
git add packages/<apps-or-extra>/<name>/ packages/system/<name>-rd/

The repo's pre-commit CI job runs make generate in every package and then git diff --exit-code. Any unstaged generator output fails the job with exit code 123 and blocks the PR. Also rerun make generate after a git commit --amend if the amended change touched any of the sources above.

To locate packages a WIP branch likely needs to be regenerated:

git diff --name-only | xargs -n1 dirname | sort -u | grep ^packages/

Commit Format

Follow Conventional Commits with --signoff:

git commit --signoff -m "type(scope): brief description"

Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore

Scopes (e.g., not exhaustive — use any scope that names the component you are touching):

  • System: dashboard, platform, cilium, kube-ovn, linstor, fluxcd, cluster-api
  • Apps: postgres, mariadb, redis, kafka, clickhouse, virtual-machine, kubernetes
  • Other: api, hack, tests, ci, docs, agents, maintenance

Breaking changes: append ! after type/scope (feat(api)!: ...) or add a BREAKING CHANGE: footer.

Examples:

git commit --signoff -m "feat(dashboard): add config hash annotations to restart pods on config changes"
git commit --signoff -m "fix(postgres): update operator to version 1.2.3"
git commit --signoff -m "docs(contributing): add installation guide"

AI Agent Attribution

When an AI agent authors or materially assists with a commit, add an Assisted-By: trailer naming the model:

Assisted-By: Claude <noreply@anthropic.com>
Assisted-By: GPT-5 <noreply@openai.com>
Assisted-By: Gemini <noreply@google.com>

This sits alongside the Signed-off-by: trailer produced by --signoff. Use one trailer per model if multiple contributed.

Rebasing on upstream/main

If the branch has extra commits, clean it up:

git fetch upstream
git checkout -b my-feature upstream/main
git cherry-pick <your-commit-hash>
git push -f origin my-feature

Pull Request Body

Fill in the template at .github/PULL_REQUEST_TEMPLATE.md. It includes the required release-note block.

Create the PR with gh pr create --title "type(scope): brief description" --body-file <file>.

Fetching Unresolved Review Comments

Cozystack uses GitHub review threads with resolution status. Only unresolved threads are actionable — resolved threads are already handled.

The REST endpoint /pulls/{pr}/reviews returns review summaries, not individual review comments. Use the GraphQL API to access reviewThreads with isResolved status:

gh api graphql -F owner=cozystack -F repo=cozystack -F pr=<PR_NUMBER> -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
  repository(owner: $owner, name: $repo) {
    pullRequest(number: $pr) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 100) {
            nodes {
              id
              path
              line
              author { login }
              bodyText
              url
              createdAt
            }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | .comments.nodes[]'

Compact one-line variant:

gh api graphql -F owner=cozystack -F repo=cozystack -F pr=<PR_NUMBER> -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
  repository(owner: $owner, name: $repo) {
    pullRequest(number: $pr) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 100) {
            nodes {
              path
              line
              author { login }
              bodyText
            }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | .comments.nodes[] | "\(.path):\(.line // "N/A") - \(.author.login): \(.bodyText[:150])"'