Capability 004: Rules and Tools¶
Status: Accepted
Context¶
An assistant follows a rule less reliably the more rules it loads at once (mission statement; target picture, section Rules, Guidelines, and Tools). This capability keeps the rules a generated repository loads into every session to one short core file, loads every other rule only for the files it governs, limits the size of each file, and leaves whatever a tool can check to that tool. It also brings the requirements guideline in line with the Capability Specification of capability 003.
References¶
Details¶
Rule files of module ai, relative to the artifact directory. A rule derived from a guideline
holds that guideline's ## Directives section. Source files are the files of the artifact's
language: **/*.go; **/*.java; **/*.cpp, **/*.hpp, **/*.h; **/*.ts, **/*.tsx.
| Rule | Loaded for | Profiles |
|---|---|---|
core.md |
Every session | All |
bash_coding.md |
**/*.sh |
All |
ci_cd.md |
.gitlab-ci.yml, **/*.gitlab-ci.yml, .github/workflows/** |
All |
tool_chain.md |
devbox.json and the files of ci_cd.md |
All |
makefile_coding.md |
Makefile, Makefile.d/**, Makefile.local |
All |
technical_writing.md |
**/*.md |
All |
requirements.md |
specs/capabilities/** |
All |
testing.md |
test/**, **/*_test.go, src/test/**, **/*.test.ts, **/*.test.tsx |
All except electronics |
general_coding.md, error_handling.md, security.md, refactoring.md, oo_design_and_programming.md, library_design.md |
Source files | All except electronics |
data_modeling.md |
specs/functional_design/domain_model.md and source files |
All except electronics |
<language>_coding.md |
Source files | Per language |
cpp_embedded_coding.md |
Source files | Firmware |
cpp_library_coding.md |
Source files | C++ library |
can_bus.md |
**/*.dbc, **/can*.hpp, **/can*.cpp |
Firmware |
cli_tool.md, user_experience.md |
Source files | Tool |
containerization.md |
**/Dockerfile*, **/*.dockerfile, image/** |
Profiles that build an image |
api_design.md |
specs/technical_design/APIs/** and source files |
Service |
business_process_design.md, service_design.md, logging.md, monitoring.md, performance.md, frontend_integration.md |
Source files | Service |
js_coding.md, ui_architecture.md, user_experience.md, ui_design_input.md |
Source files | Frontend |
responsive_web.md |
**/*.css, **/*.tsx, **/*.jsx |
Frontend |
schematic_design.md |
**/*.kicad_sch |
Electronics |
pcb_layout_design.md |
**/*.kicad_pcb |
Electronics |
The guideline git.md yields no rule; its directives that matter in every session are part of
core.md.
The root of a mono-repository gets core.md, bash_coding.md, ci_cd.md, tool_chain.md,
makefile_coding.md, technical_writing.md, and requirements.md.
.github/copilot-instructions.md holds the core rule, so it is generator-owned, unlike
CLAUDE.md. .markdownlint-cli2.jsonc names the Markdown files make lint checks, and
.markdownlint.json the rules; both belong to module scaffold and are generator-owned.
make lint-markdown runs markdownlint from the image the CI pipeline uses. The root of a
mono-repository gets both files, a make lint-markdown target, and a pipeline job of its own; there
they cover the root's Markdown files only.
Pipeline tools, by the forge of ci:
ci |
devbox.json lists |
make ci-lint runs |
make ci-local runs |
|---|---|---|---|
gitlab |
glab, gitlab-ci-local |
glab ci lint |
gitlab-ci-local |
github |
gh, actionlint, act |
actionlint |
act |
The pipeline of a mono-repository lives at its root, so the root Makefile has both targets and an
artifact's Makefile has neither; ARTIFACT=<directory> runs that artifact's pipeline only.
Word budgets:
| File | Words at most |
|---|---|
CLAUDE.md |
400 |
.claude/rules/core.md |
400 |
Any other file in .claude/rules/ |
300 |
.github/copilot-instructions.md |
800 |
Any file in .github/instructions/ |
300 |
Functional Requirements¶
- Every session loads one core rule. It states the development workflow of the target picture,
how to keep specs and code consistent, and the directives of
git.mdthat apply to every commit. - Every other rule loads only while the assistant works on the files it governs, and an artifact gets only the rules that apply to its profile, as listed in Details.
- Claude Code and GitHub Copilot get the same rules, each in its own format:
.claude/rules/withpaths:, and.github/copilot-instructions.mdfor the core rule plus.github/instructions/*.instructions.mdwithapplyTo:. - What a tool can check, a tool checks:
make lintruns markdownlint on every Markdown file and shellcheck on every shell script, in every profile. - The requirements guideline describes how to write the requirements and acceptance criteria of a
Capability Specification and applies to
specs/capabilities/. - The root of a mono-repository with module
aigets the core rule and the rules Details lists for it. - The root of a mono-repository lints its own Markdown files, not those of its artifacts, with
make lint-markdownand a job of its pipeline. - A developer lints the pipeline and runs it locally in Docker before pushing it, with the tools
of Details for the forge of
ci.
Non-Functional Requirements¶
- Every file an assistant loads as instructions stays within its word budget of Details, for every profile, both assistants, and the root of a mono-repository.
Technical Requirements¶
None.
Error Handling¶
None.
Out of Scope¶
- The guidelines' text outside their
## Directivessections, exceptrequirements.md - Which guidelines module
guidelinescopies - Skills, agents, commands, and hooks
- Lint rules of the language linters beyond their current configuration
- The generator's own rules (capability 005)
- Reporting files that a newer generator version no longer generates
Acceptance Criteria¶
- Go service with default modules and assistant
claude:.claude/rules/holds exactlycore.mdand the rules Details lists for a Go service;core.mdhas nopaths:, every other file has the patterns of Details. - Same with assistant
copilot:.github/copilot-instructions.mdcontains the text ofcore.md; every file in.github/instructions/hasapplyTo:with the patterns of Details. - Every profile, both assistants, single repository and mono-repository root: every file of Details is within its word budget.
- C++ firmware with assistant
claude: noperformance.md,user_experience.md,js_coding.mdin.claude/rules/;data_modeling.md,library_design.md,cpp_embedded_coding.md, andcan_bus.mdpresent. - Go service with assistant
claude: nojs_coding.md,ui_architecture.md,user_experience.mdin.claude/rules/. - Go service with assistant
claude:.claude/rules/requirements.mdhaspaths:specs/capabilities/**and contains neitherFUNC-REQnorspecs/requirements. - Go service with assistant
claude:.claude/rules/core.mdnamesspecs/capabilities/,Accepted,test/bdd/features/, and Conventional Commits; no.claude/rules/spec_consistency.md, no.claude/rules/git.md. - Go service and C++ firmware generated by
make examples:make lintsucceeds; with a trailing space appended toREADME.md, it fails. - Mono-repository with the artifacts
plannerandbridgeand assistantclaude: the root.claude/rules/holds exactly the files Details lists for the root. - Mono-repository with
ci: gitlaband withci: github: the rootMakefilehas the targetlint-markdown, the root pipeline runs markdownlint, and the root.markdownlint-cli2.jsonccovers every Markdown file of the root and names no path below an artifact directory. - Every profile: no generated
devbox.jsonlists markdownlint. - Go library and C++ firmware with
ci: gitlab, Go library and KiCad electronics withci: github:devbox.jsonlists the tools of Details for thatci, and theMakefilehas the targetsci-lintandci-localrunning them. - Mono-repository with the artifacts
plannerandbridge, withci: gitlaband withci: github: the rootMakefilehas the targetsci-lintandci-local, theMakefileofplannerhas neither.
Decisions¶
- The core rule is a template of its own, not extracted from the guidelines.
Its content is a selection across guidelines and the workflow; extracting it would need
markers in every guideline.
Consequence: a directive in
core.mdcan repeat one of a guideline; the generator's review keeps both consistent. - Every rule derived from a guideline is path-scoped.
A rule loaded into every session competes with every other rule, whether the session touches
its subject or not.
Consequence: a guideline without files of its own, such as
git.md, yields no rule; a session that reads no matching file does not see a scoped rule, so skills and agents name the guideline they rely on by topic. - A budget in words per file, checked by the generator's tests. Rules grow with every correction; a fixed budget forces replacing a directive instead of adding one. Consequence: a new directive in a full file shortens or removes another one.
- A directive that a tool checks does not appear in a rule.
The tool reports every violation; the rule only competes for attention.
Consequence: removing such a directive requires the tool to run in
make lint; whether a rule still repeats a tool's check is a matter of review, not of a test. spec_consistency.mdbecomes part ofcore.md. Keeping specs and code consistent applies to every session, like the workflow it belongs to. Consequence:repo updatelists files no longer generated only for a removed module or artifact, so an existing repository keeps.claude/rules/spec_consistency.md,.claude/rules/git.md, and the rules a profile no longer gets until the developer deletes them.- Rules follow the profile, not every guideline the docs site offers. A rule about user interfaces does not help a firmware, and loading it costs attention. Consequence: services no longer get the frontend rules; a service that serves a user interface needs a frontend artifact or the guideline on the docs site.
- markdownlint and ShellCheck run from the CI images, also locally.
Their configuration and the
Makefileare generator-owned,devbox.jsonis not; a tool listed there would not reach an existing repository. A tool preinstalled on GitHub's runner has a version nobody pinned and is missing whereactruns the workflow. Consequence:make lintneeds Docker, likemake docs, and a change to the lint rules is proposed to the generator. - The pipeline tools come from devbox, not from images.
actandgitlab-ci-localstart containers themselves, andglabandghneed the developer's login; neither works well inside a container. Consequence: they reach only a newly generateddevbox.json; an existing repository adds them withdevbox add. The root of a mono-repository gets nodevbox.json, so its targets need the tools from an artifact's devbox or a rootdevbox.jsonof the developer's own.actruns on the host's architecture, so a job can behave differently on anarm64host than on GitHub'samd64runner.