Skip to content

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

  1. 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.md that apply to every commit.
  2. 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.
  3. Claude Code and GitHub Copilot get the same rules, each in its own format: .claude/rules/ with paths:, and .github/copilot-instructions.md for the core rule plus .github/instructions/*.instructions.md with applyTo:.
  4. What a tool can check, a tool checks: make lint runs markdownlint on every Markdown file and shellcheck on every shell script, in every profile.
  5. The requirements guideline describes how to write the requirements and acceptance criteria of a Capability Specification and applies to specs/capabilities/.
  6. The root of a mono-repository with module ai gets the core rule and the rules Details lists for it.
  7. The root of a mono-repository lints its own Markdown files, not those of its artifacts, with make lint-markdown and a job of its pipeline.
  8. 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

  1. 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 ## Directives sections, except requirements.md
  • Which guidelines module guidelines copies
  • 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

  1. Go service with default modules and assistant claude: .claude/rules/ holds exactly core.md and the rules Details lists for a Go service; core.md has no paths:, every other file has the patterns of Details.
  2. Same with assistant copilot: .github/copilot-instructions.md contains the text of core.md; every file in .github/instructions/ has applyTo: with the patterns of Details.
  3. Every profile, both assistants, single repository and mono-repository root: every file of Details is within its word budget.
  4. C++ firmware with assistant claude: no performance.md, user_experience.md, js_coding.md in .claude/rules/; data_modeling.md, library_design.md, cpp_embedded_coding.md, and can_bus.md present.
  5. Go service with assistant claude: no js_coding.md, ui_architecture.md, user_experience.md in .claude/rules/.
  6. Go service with assistant claude: .claude/rules/requirements.md has paths: specs/capabilities/** and contains neither FUNC-REQ nor specs/requirements.
  7. Go service with assistant claude: .claude/rules/core.md names specs/capabilities/, Accepted, test/bdd/features/, and Conventional Commits; no .claude/rules/spec_consistency.md, no .claude/rules/git.md.
  8. Go service and C++ firmware generated by make examples: make lint succeeds; with a trailing space appended to README.md, it fails.
  9. Mono-repository with the artifacts planner and bridge and assistant claude: the root .claude/rules/ holds exactly the files Details lists for the root.
  10. Mono-repository with ci: gitlab and with ci: github: the root Makefile has the target lint-markdown, the root pipeline runs markdownlint, and the root .markdownlint-cli2.jsonc covers every Markdown file of the root and names no path below an artifact directory.
  11. Every profile: no generated devbox.json lists markdownlint.
  12. Go library and C++ firmware with ci: gitlab, Go library and KiCad electronics with ci: github: devbox.json lists the tools of Details for that ci, and the Makefile has the targets ci-lint and ci-local running them.
  13. Mono-repository with the artifacts planner and bridge, with ci: gitlab and with ci: github: the root Makefile has the targets ci-lint and ci-local, the Makefile of planner has neither.

Decisions

  1. 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.md can repeat one of a guideline; the generator's review keeps both consistent.
  2. 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.
  3. 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.
  4. 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.
  5. spec_consistency.md becomes part of core.md. Keeping specs and code consistent applies to every session, like the workflow it belongs to. Consequence: repo update lists 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.
  6. 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.
  7. markdownlint and ShellCheck run from the CI images, also locally. Their configuration and the Makefile are generator-owned, devbox.json is 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 where act runs the workflow. Consequence: make lint needs Docker, like make docs, and a change to the lint rules is proposed to the generator.
  8. The pipeline tools come from devbox, not from images. act and gitlab-ci-local start containers themselves, and glab and gh need the developer's login; neither works well inside a container. Consequence: they reach only a newly generated devbox.json; an existing repository adds them with devbox add. The root of a mono-repository gets no devbox.json, so its targets need the tools from an artifact's devbox or a root devbox.json of the developer's own. act runs on the host's architecture, so a job can behave differently on an arm64 host than on GitHub's amd64 runner.