docs(ai): document the repository's Go conventions as a generated skill - #200
Merged
Conversation
The repository states what to change and what to document, but never how the Go itself should read: how much a godoc owes a caller, when an inline comment earns its line, where a long call breaks, which file a new function belongs in. Reviewers carried that in their heads and every contributor rediscovered it. Add .ai/how-we-write-go.md as the source of those conventions, ported from the camunda-operator skill of the same name and rewritten around this repository: the 120-character soft limit and break-after-paren shape that pkg/ already uses (nothing in `make fmt` reflows Go), the builder/resource/mutator/component layering and the rule that mutators, editors, gates and status handlers stay free of I/O, pkg/ as public API against internal/, and the fixed file roles of a primitive package. The operator-side sections of the original are dropped: this is a framework, not an operator. Generate it into .claude/skills/how-we-write-go/SKILL.md from ai-instructions-gen, and point CLAUDE.md, .junie/guidelines.md and the Copilot instructions at the tracked source, since neither Junie nor Copilot reads .claude/skills. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AkugYZxCwKb17i8gfFj4tR
There was a problem hiding this comment.
🟡 Changes recommended
There are a couple of concrete accuracy/consistency issues in the new guide and generation flow (notably make all/examples and make fmt wording, plus deterministic generation ordering for the new .claude/skills copy).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR adds a repository-specific “house Go style” guide (.ai/how-we-write-go.md) and wires it into the existing AI-instructions generation flow so contributors (and AI tooling) have a single, tracked source of Go writing conventions for this framework.
Changes:
- Add
.ai/how-we-write-go.mddescribing GoDoc, inline comments, formatting/line breaks, layering, naming, errors, and file organization conventions. - Update AI instruction entrypoints (
.ai/base.md, generated.github/copilot-instructions.md) to point contributors at the new guide. - Extend
make ai-instructions-gento generate a Claude skill file at.claude/skills/how-we-write-go/SKILL.md.
File summaries
| File | Description |
|---|---|
| Makefile | Adds .ai/how-we-write-go.md to AI generation; copies it into .claude/skills/how-we-write-go/SKILL.md. |
| .github/copilot-instructions.md | Adds a “House Go style” section referencing .ai/how-we-write-go.md. |
| .ai/how-we-write-go.md | New Go conventions guide intended to be the canonical “house style” source. |
| .ai/base.md | Adds the “House Go style” subsection so generated instruction entrypoints link to the guide. |
Review details
Suppressed comments (1)
Makefile:66
ai-instructionscurrently relies on prerequisite ordering (ai-instructions-gen fmt-md). With the new.claude/skills/.../SKILL.mdcopy, this can leave the generated skill out of sync iffmt-mdrewrites.ai/how-we-write-go.mdafter it was copied (and Make may also run prerequisites in parallel under-j). Consider makingai-instructionsa recipe that formats first, generates, then formats again so the outputs are deterministic and the copied skill stays byte-identical to the source.
AI_GO := .ai/how-we-write-go.md
.PHONY: ai-instructions
ai-instructions: ai-instructions-gen fmt-md
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+200
to
+202
| Nothing in `make fmt` reflows Go source: `gofmt` and `goimports` normalise indentation and imports, and leave your line | ||
| breaks exactly where you put them. The soft limit is 120 characters, the same width prettier applies to Markdown here, | ||
| and holding it is your job rather than a tool's. |
Comment on lines
+657
to
+658
| **Every public change lands with its example.** `examples/` is compiled and run by `make all`, and each directory | ||
| demonstrates one concept. A new capability that no example exercises is a capability nobody will find. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The repository tells a contributor what to change and what to document, but never how the Go itself
should read: how much a godoc owes a caller, when an inline comment earns its line, where a long call
breaks, which file a new function belongs in. That knowledge lived in reviewers' heads, so every
contributor rediscovered it and every review spent time on it. This adds
.ai/how-we-write-go.mdasthe written source of those conventions and generates it into a
how-we-write-goskill alongside theexisting AI instruction files. It is documentation only: no Go source changes, and nothing here is
enforced by a linter, so the conventions bind by being read rather than by failing CI.
Changes
.ai/how-we-write-go.md: 18 sections covering doc comments, inline comments, whitespace rhythm,line breaking, code bloat, layering and side effects, typed string constants, error wrapping,
naming, context propagation, interface design, panic vs error, where code lives, and order within a
file. Ported from the camunda-operator skill of the same name.
limit and the break-after-paren shape
pkg/already uses, because nothing inmake fmtreflows Go(
gofmtandgoimportsleave line breaks alone) and there is nogolineshere. The controllerlayering section became builder/resource/mutator/component, with the rule that mutators, editors,
gates and status handlers stay free of I/O so golden tests keep running without a cluster. "Where to
put code" became
pkg/as public API againstinternal/, plus the file roles a primitive packagealways has. Examples are grounded on real symbols:
concepts.ConvergingOperation,concepts.Alive,component.OperatorCRDembeddingclient.Object,NewPolicyRulesEditor's panic.logs, the status-condition model, reconcile requeue patterns, and CRD kubebuilder/CEL validation.
This is a framework, not an operator.
ai-instructions-gennow also writes.claude/skills/how-we-write-go/SKILL.md, and.ai/base.mdgained a "House Go style" subsection so
CLAUDE.md,.junie/guidelines.mdand.github/copilot-instructions.mdall point at the tracked source. Junie and Copilot cannot read.claude/skills/, and.claude/*is gitignored here, so the tracked file has to be the one theyare sent to.
Related
(a line-length linter, an import-boundary check between
pkg/andinternal/), that is a separatechange.
Testing
make ai-instructionsruns clean and the generatedSKILL.mdis byte-identical to.ai/how-we-write-go.md;prettier reports both unchanged on a second pass, so the source is already at its formatted fixed point
and the frontmatter
descriptionstays on a single line rather than folding across lines.Every claim the guide makes about this repository was checked against the source rather than carried
over from the original. Line-length behaviour was measured across
pkg/,internal/andcmd/; theprimitive file-role claim was verified against all 21 primitive packages; and four examples that did
not match the real API were corrected:
Component.Reconcile's signature,concepts.Alive's methodname (
ConvergingStatus, notAliveStatus), theNewComponentBuildercall shape, and mutatormethods returning nothing.
No Go source changed, so
make allbehaviour is unaffected by this diff.