Workflow
How work gets from an issue to a published chart. The binding short form lives in CLAUDE.md; this page is the long form with the reasons.
The roles
The main Claude session is the task manager. It does not implement issues itself. Implementation happens in a dedicated development agent that owns one issue, one branch and one PR from start to merge.
The split exists so that planning stays reviewable: a plan that is written, approved and recorded before any code is written can be argued with. A plan discovered afterwards in a diff cannot.
The eight steps
- Plan first, get approval. The manager presents a plan for the issue and waits for explicit approval. No implementation before that.
- Document the final plan on the issue. Once approved, it is posted as a comment before implementation starts — skipped only if the issue body already contains the full plan. Later decisions go there as comments too, so the issue stays the record.
- Delegate the implementation. A development agent implements the issue completely on its own branch and opens a PR.
- The agent handles PR comments. It watches its PR, addresses new review comments with code changes, replies on the thread and marks the thread resolved.
- Update the wiki — as part of the issue, before the merge is requested, so that code and documentation are reviewed together. See below. It is part of the work, not a follow-up.
- The agent terminates itself once its PR has been merged or closed.
- The user merges. Never merge yourself, and never arm auto-merge on your own PR. Only after the merge may work on the next issue begin.
- Verify the linked issue was closed after the merge — and that the wiki edit really landed. Gitea auto-closes on the same keywords as GitHub, but only for an issue in the same repository; a migrated issue whose number changed is closed by hand.
The wiki is part of the work
This wiki is the knowledge base. A change that lands in main while the wiki still describes the old state has not been finished — it has been half-finished in a way that is invisible, because nothing fails.
What obliges an edit, in the same round of work as the change:
| Change | Page to update |
|---|---|
| a value added, removed, renamed, or its default changed | the chart's page — the values table and, if the behaviour moved, the operating notes |
| runtime behaviour changed (probes, hardening, restart semantics, required values) | the chart's page, plus Lessons learned if the reason is one others could repeat |
| a new chart | a new chart page, plus a row in the chart index and an entry in _Sidebar.md |
| a convention added or changed | Chart style guide |
| pipeline, fixture or runner behaviour changed | CI/CD |
| the issue workflow itself changed | this page — and CLAUDE.md, which is the binding copy |
| a Renovate rule added or changed | Renovate |
| something broke in a way that a rule now prevents | Lessons learned |
What does not oblige an edit: an app-version bump, at any level. Renovate automerges those continuously and does not touch the wiki; chart pages therefore carry no version numbers at all and point at Chart.yaml instead. If an app-version bump does change behaviour or values, it is no longer a plain bump and the table above applies.
Since Gitea #128, "plain" is mechanically defined rather than left to judgement: the chart version now states the size of the jump, because ci/renovate-bump-chart.sh takes it from Renovate's update type — an app minor is a chart minor (see Versioning). What that decision deliberately did not add is a duty to look: nobody is obliged to read the release notes of a bump, whatever level it carries. The limit is named here rather than hidden, because it is the one that let the security default a patch bump switched off through — the number stopped understating, and that is the whole of the remedy.
Where the duty sits in the workflow: the development agent updates the wiki as part of its issue, before asking for the merge, so that the reviewer sees code and documentation together. The manager checks it at step 8, along with the issue closure.
How to edit. The wiki is a separate git repository:
git clone ssh://git@git.jk-dev.de:30022/jlab-cluster/helm-charts.wiki.git
# edit the .md files, one page per file, flat layout
git -C helm-charts.wiki commit -am "outline: document the new upload ceiling"
git -C helm-charts.wiki push
Page names are file names: outline.md is the page outline. Links between pages are relative page names without the extension — [CI/CD](CI-CD). _Sidebar.md is the navigation shown beside every page; a new page that is not listed there is reachable only by search.
Fetch and rebase before every push, and never force-push — and note that the wiki's default branch is main, not master, so the rebase is onto origin/main. The wiki has no PR flow and no review, so two people — or two agents — edit the same page at the same time without noticing: during Gitea #16 and #18 that happened twice within minutes, and only luck made the rebase clean. A force push here deletes the other edit silently, with nothing left to report it.
Rules for every commit, PR, issue and comment
- No
Co-Authored-Bytrailer and no "Generated with Claude Code" footer. - Commits must be signed. In the Coder workspace that needs no extra step — its own SSH signer does it — but verify before opening the PR:
git log --format='%G?' -1must printG. If signing fails, stop and report rather than pushing unsigned work; branch protection rejects unsigned commits onmain, and discovering that at merge time wastes the review. - A PR that does not finish its issue writes
Part of #n, neverFixes #n. The forge readsFixesas an instruction to close the issue at merge, so putting it on a PR that deliberately leaves work behind files an open task as done. The repair — reopening the issue by hand and recording what is left — depends on somebody remembering that the PR was partial, and nobody rereads a merged PR body. This is not hypothetical: Gitea PR #48 replaced the outdated sentence in twenty charts but not inrss-bridge, which had to be dropped because its install test fails on the runner (Gitea #51), and the decision was explicitly that Gitea #40 stays open until the remainder is caught up. The PR text carriedFixes #40anyway; the merge closed #40 with one occurrence still open, and it was reopened by hand only because the implementing agent happened to think of it. This way of working produces the case regularly — one issue and several PRs, a chart taken out of a sweep, a finding that earns its own issue — so the keyword is chosen against the PR's actual scope and not copied out of the template. Step 8 above verifies the auto-close; that check is only worth anything if the keyword was right to begin with. - Write new issue references with the Gitea number.
#ninside the repo's files means the old GitHub tracker, and Gitea silently resolves a bare#nagainst its own counter — so an old reference can render as a link to something unrelated. See Forge and tooling.
Documentation that is not the wiki
CLAUDE.md— the binding short form of this workflow. Changes to the workflow go here first; this page follows.README.md— repository information for someone reading the code: what the charts are, how the pipelines work, the style guide. Any PR that changes repo-wide behaviour updates it in the same PR, and it links here for the long form.NOTES.txtper chart — what an operator needs after an install, rendered against the values actually set. It is the per-release version of a chart page and is required for every chart.
The division: CLAUDE.md binds the agent, README.md explains the repository, the wiki explains the system, NOTES.txt explains one release.
helm-charts wiki
How we work
How it is built
How charts are written
Charts
- apache-tika
- bentopdf
- bulwark
- calibre-web-automated
- convertx
- cyberchef
- freesailarr
- garage
- gotenberg
- homeassistant
- keycloak
- matrix-synapse
- minecraft-router
- minecraft-server
- outline
- paperless-ngx
- patchmon
- rallly
- rss-bridge
- samba
- satisfactory
- searxng
- stalwart
- sure
- teamspeak-server
- template-chart
- urlaubsverwaltung
- valkey
- voucher-vault
- ytdlp-web-player
- zipline