Skip to content

Add CLAUDE.md files for Claude Code guidance#1273

Open
tgymnich wants to merge 5 commits intomainfrom
tim/claude
Open

Add CLAUDE.md files for Claude Code guidance#1273
tgymnich wants to merge 5 commits intomainfrom
tim/claude

Conversation

@tgymnich
Copy link
Copy Markdown
Contributor

@tgymnich tgymnich commented Apr 7, 2026

Add top-level CLAUDE.md with project overview, build/test commands,
compilation flow, runtime options, and architecture. Add water/CLAUDE.md
and waveasm/CLAUDE.md covering each optional extension's build workflow,
dialect design, and pass pipeline.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 7, 2026

Water Code Coverage

Filename                                                           Functions  Missed Functions  Executed       Lines      Missed Lines     Cover    Branches   Missed Branches     Cover
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
lib/Transforms/MemrefDecomposition.cpp                                    28                 0   100.00%         600                49    91.83%         104                46    55.77%
lib/Transforms/AllocToAlloca.cpp                                           2                 0   100.00%          17                 0   100.00%           0                 0         -
lib/Transforms/CheckStaticAssertions.cpp                                   2                 0   100.00%          22                 1    95.45%           8                 4    50.00%
lib/Transforms/GPUModuleToBinary.cpp                                      19                 5    73.68%         339               115    66.08%         128                57    55.47%
lib/Transforms/DropTransformOps.cpp                                        2                 0   100.00%          16                 0   100.00%           2                 0   100.00%
lib/Transforms/GPUToGPURuntime.cpp                                        14                 0   100.00%         298                23    92.28%          40                17    57.50%
lib/Transforms/SLPVectorizer.cpp                                          61                 3    95.08%        1065                97    90.89%         558               163    70.79%
lib/Transforms/AccessCheckers.cpp                                         35                 1    97.14%         446                40    91.03%         124                30    75.81%
lib/Transforms/AssembleISA.cpp                                             4                 1    75.00%          30                 2    93.33%           2                 1    50.00%
lib/Dialect/Wave/Transforms/LoweringPatterns.cpp                          48                 2    95.83%         965               147    84.77%         272                82    69.85%
lib/Dialect/Wave/Transforms/PropagateDefaultsFromConstraints.cpp           3                 3     0.00%          35                35     0.00%          12                12     0.00%
lib/Dialect/Wave/Transforms/TypeConverter.cpp                              7                 2    71.43%          96                26    72.92%          32                17    46.88%
lib/Dialect/Wave/Transforms/LowerReadWriteOps.cpp                         10                 0   100.00%         236                18    92.37%          58                11    81.03%
lib/Dialect/Wave/Transforms/DetectNormalForms.cpp                          4                 0   100.00%          48                 0   100.00%           8                 0   100.00%
lib/Dialect/Wave/Transforms/ExpandVariadicReductions.cpp                   2                 0   100.00%          24                 1    95.83%           6                 1    83.33%
lib/Dialect/Wave/Transforms/InferTypes.cpp                                62                11    82.26%         920                94    89.78%         362               153    57.73%
lib/Dialect/Wave/Transforms/LowerWaveToMLIR.cpp                            5                 0   100.00%         130                 1    99.23%          16                 2    87.50%
lib/Dialect/Wave/Transforms/InferIndexExprs.cpp                            3                 0   100.00%          34                 1    97.06%           8                 1    87.50%
lib/Dialect/Wave/Transforms/Utils.cpp                                      4                 0   100.00%          64                 5    92.19%          20                 4    80.00%
lib/Dialect/Wave/Transforms/ResolveDistributedAllocations.cpp              7                 0   100.00%         183                16    91.26%          32                14    56.25%
lib/Dialect/Wave/IR/IndexExprInference.cpp                               174                17    90.23%        3334               291    91.27%        1372               493    64.07%
lib/Dialect/Wave/IR/WaveOps.cpp                                           91                10    89.01%        1645               186    88.69%         742               140    81.13%
lib/Dialect/Wave/IR/WaveAttrs.cpp                                         73                 5    93.15%         963                86    91.07%         424                61    85.61%
lib/Dialect/Wave/IR/IndexExpr.cpp                                         11                 0   100.00%         119                 1    99.16%          24                 3    87.50%
lib/Dialect/Wave/IR/WaveDialect.cpp                                       14                 0   100.00%         485                 9    98.14%         170                 5    97.06%
lib/Dialect/Wave/IR/WaveTypes.cpp                                          9                 1    88.89%          75                 8    89.33%          18                 3    83.33%
lib/Dialect/Wave/IR/WaveInterfaces.cpp                                    45                 0   100.00%         781                45    94.24%         338                47    86.09%
lib/Dialect/Wave/IR/WaveUtils.cpp                                         23                 0   100.00%         220                 8    96.36%          84                13    84.52%
lib/Dialect/NormalForm/Transforms/LowerNormalFormModule.cpp                3                 0   100.00%          34                 6    82.35%           8                 2    75.00%
lib/Dialect/NormalForm/IR/NormalFormDialect.cpp                            1                 0   100.00%           6                 0   100.00%           0                 0         -
lib/Dialect/NormalForm/IR/NormalFormOps.cpp                               12                 0   100.00%         201                 9    95.52%          58                 7    87.93%
lib/Pipelines/Pipelines.cpp                                                2                 0   100.00%          27                 0   100.00%           0                 0         -
lib/Analysis/InUseForSpeculation.cpp                                      12                 1    91.67%         142                 8    94.37%          32                 4    87.50%
include/water/Dialect/Wave/Transforms/LoweringPatterns.h                   1                 0   100.00%           3                 0   100.00%           0                 0         -
include/water/Dialect/Wave/IR/IndexExpr.h                                  1                 0   100.00%          10                 0   100.00%           2                 0   100.00%
include/water/Dialect/Wave/IR/WaveInterfaces.h                            40                 3    92.50%         159                 8    94.97%           8                 2    75.00%
include/water/Dialect/Wave/IR/WaveTypes.h                                  1                 0   100.00%           5                 0   100.00%           4                 0   100.00%
include/water/Dialect/Wave/IR/WaveUtils.h                                  1                 0   100.00%           5                 0   100.00%           4                 1    75.00%
include/water/Dialect/Wave/IR/WaveAttrs.h                                  4                 0   100.00%          14                 0   100.00%           0                 0         -
include/water/Dialect/NormalForm/IR/NormalFormInterfaces.h                 1                 1     0.00%           4                 4     0.00%           0                 0         -
include/water/Analysis/InUseForSpeculation.h                              12                 3    75.00%          39                17    56.41%          16                10    37.50%
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TOTAL                                                                    853                69    91.91%       13839              1357    90.19%        5096              1406    72.41%

Download full HTML report

@tgymnich tgymnich force-pushed the tim/claude branch 3 times, most recently from 34428e7 to a17c11e Compare April 7, 2026 13:09
@martin-luecke
Copy link
Copy Markdown
Contributor

Does it make sense to use AGENTS.md files instead to support different providers? e.g. cursor, copilot and so on?

@tgymnich
Copy link
Copy Markdown
Contributor Author

tgymnich commented Apr 7, 2026

Does it make sense to use AGENTS.md files instead to support different providers? e.g. cursor, copilot and so on?

Looks like we'll need to add a CLAUDE.md containing See @AGENTS.md for this to work. https://code.claude.com/docs/en/memory#agents-md

I'll make the necessary changes.

@Hardcode84
Copy link
Copy Markdown
Contributor

I have this in my global CLAUDE.md, idk if it makes sense to add here.

General LLVM/MLIR C++ tips:
* Do not use {} for single-line ifs.
* Avoid `auto` if the type is not trivial to infer; lambdas and iterators are fine.
* Do not name variables `module` to avoid collision with C++ modules.
* Prefer `std::array` over `std::vector`/`llvm::SmallVector` when the count is known at compile time.
* Use descriptive asserts through `&& "message"`.
* Use `Op::create(builder, ...)` syntax.
* Use `cast<Type>(arg)` syntax.
* Prefer `llvm::seq` to C for loops.

MLIR gotchas:
* Use `getConstantIntValue(Value/Attribute)` to extract a constant int from either a Value or an Attribute — no need to manually match arith.constant ops.
* Prefer `StringRef` and `Twine` over `std::string` for string handling.
* `DenseMap::lookup(key)` returns a default-constructed value if the key is not found, avoiding accidental insertion that `operator[]` causes.
* Do not root passes on concrete ops until absolutely necessary; prefer rooting on broader interfaces or dialects.
* `op.walk(...)` lambdas can return `WalkResult::interrupt()` to stop early and propagate failure; check the result with `.wasInterrupted()`.
* Use `return signalPassFailure();` to abort a failed pass.
* Prefer named accessor to `getResult(0)` when possible.
* In LIT tests, never use raw SSA names (`%0`, `%1`, etc.) in CHECK lines — always capture them with placeholders (e.g., `[[VAL:%.*]]`) and reuse the placeholder.

General python tips:
* Prefer `math.prod` over `reduce`.
* Iteration over `set` is not stable.
* Underscore-prefixed names are module-private. Do not import them across modules — either drop the underscore or move the function somewhere public.
* Use `contextlib.suppress(ExcType)` instead of bare `try/except/pass`.
* Prefer `pathlib.Path` over `os.path` — use `/` operator, `.exists()`, `.read_text()`, etc.
* Avoid local imports if possible.

Comment thread .gitignore
requirements-pytorch-rocm-generated.txt

# Claude
CLAUDE.local.md
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gitignores a CLAUDE.local.md file, but I would like the main CLAUDE.md (or AGENTS.md) to explicitly reference and tell the model to also adhere to an AGENTS.local.md file -- from what I've read, most agent programs don't read an AGENTS.local.md, and it seems that claude doesn't use CLAUDE.local.md anymore either. I think this is a shame. Anyway, we will all have some personal workflow stuff in addition to any shared AGENTS.md stuff. There is the global ~/.claude/CLAUDE.md and similar for other agents, but that affects all repos, and I really want to have personal and repo-specific instructions for agents.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude does still use CLAUDE.local.md:

❯ /context
  ⎿  Context Usage
     ⛁ ⛁ ⛀ ⛀ ⛀ ⛶ ⛶ ⛶ ⛶ ⛶   Claude-Sonnet-4.6 · 5k/200k tokens (3%)
     ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶
     ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶   Estimated usage by category
     ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶   ⛁ System prompt: 3.9k tokens (1.9%)
     ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶   ⛁ Memory files: 1.1k tokens (0.5%)
     ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶   ⛁ Skills: 349 tokens (0.2%)
     ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶   ⛁ Messages: 8 tokens (0.0%)
     ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶   ⛶ Free space: 162k (80.9%)
     ⛶ ⛶ ⛶ ⛝ ⛝ ⛝ ⛝ ⛝ ⛝ ⛝   ⛝ Autocompact buffer: 33k tokens (16.5%)
     ⛝ ⛝ ⛝ ⛝ ⛝ ⛝ ⛝ ⛝ ⛝ ⛝

     Memory files · /memory
     └ CLAUDE.md: 13 tokens
     └ AGENTS.md: 1k tokens
     └ CLAUDE.local.md: 19 tokens
     └ ~/.claude/projects/-home-tgymnich-wave/memory/MEMORY.md: 39 tokens

     Skills · /skills

So you should be able to still use per-repo configs.
I also added AGENTS.local.md to .gitignore.

Comment thread CLAUDE.md Outdated

## Commands

### Setup
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After #1266 lands, we can swap all of this detail for a one-line script invocation that the agent can run to have a full setup.

Comment thread CLAUDE.md Outdated

### Gotchas
- **Always set `WAVE_CACHE_ON=0`** when testing code changes — stale cache entries hide the effect of edits: `WAVE_CACHE_ON=0 pytest ...`
- DCO sign-off required on commits: `git commit -s`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to not have the agent sign off automatically. I know we need sign-off for CI, but I don't like the agent signing off for me. Lately I've been using a workflow where I have agents generate a bunch of stuff, and sometimes I push to run CI, knowing that the sign-off check will fail, but letting me do a full CI test to see if there is anything missing from a PR, then review the code and then add sign-off after I review. It's not hard to add sign-off after-the-fact. Eg. I have a git metadata script that lets me add sign-off to a range of commits: https://github.com/willghatch/dotfileswgh/blob/2331bbb8998668406b5f0d11e8c7b9fe3561a7ae/commands/git-commit-meta

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the sign-off part

@willghatch
Copy link
Copy Markdown
Contributor

I have mixed feelings about checking in a CLAUDE.md or AGENTS.md file. I DO want to share pieces of it, but I also want to always be able to inject my own repo-local config without conflicting with checked-in files, and I worry that over time the AGENTS.md check-in can become stale, or become large. I've personally been using a script that can pull in many snippets to build an AGENTS.md file, where I can add and remove default and non-default snippets, where some are global defaults (IE stuff about my workflow that I always use), some are per-project defaults, some non-default that I can manually trigger to add, etc (https://github.com/willghatch/dotfileswgh/blob/2331bbb8998668406b5f0d11e8c7b9fe3561a7ae/commands/agents-md-generate). I somewhat wish we would check in a directory of markdown files with instructions that we can pull in a la carte, but that's sort of an obtuse workflow if you're not using something like my script. I've been intending to make a skills directory and start contributing some skill files, which I think would be a great way to have re-usable instructions that don't always get loaded. Anyway, I'm not sure this comment even has something actionable about it. I'm just... unsatisfied with the AGENTS.md standard and the feeling that I'm going to get to a point where I am deleting the checked-in file with every checkout to replace it with my own, and then always having to deal with a file that git thinks is dirty, having to deal with it during rebasing, etc, and it always being a pain.

tgymnich and others added 3 commits April 8, 2026 11:35
Add top-level CLAUDE.md with project overview, build/test commands,
compilation flow, runtime options, and architecture. Add water/CLAUDE.md
and waveasm/CLAUDE.md covering each optional extension's build workflow,
dialect design, and pass pipeline.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Tim Gymnich <tim@gymni.ch>
@ imports always load at session start. Child CLAUDE.md files load
on demand automatically when Claude works in those directories.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Tim Gymnich <tim@gymni.ch>
Signed-off-by: Tim Gymnich <tim@gymni.ch>
Copy link
Copy Markdown
Contributor

@ftynse ftynse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good start in general. My overall recommendation is to point to files/scripts whenever possible to prevent instruction bitrot

Comment thread water/CLAUDE.md Outdated

```bash
# First build — builds LLVM from source, takes a while
WAVE_WATER_DIR=water/build pip install -e ".[dev]"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to pre-build water for the dir to exist?

Comment thread water/CLAUDE.md Outdated

```bash
ninja -C water/build check-water # all lit tests
lit test/Dialect/Wave/<test>.mlir -vv # single test
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tell it where to find lit (in .venv or in LLVM build/install tree). Mine gets confused a lot.

Comment thread water/CLAUDE.md Outdated

### Dialects

**`wave.*`** — primary dialect. `wave.tensor` has symbolic shapes (unknown until inferred by passes) and an address space (`Global`, `Shared`, `Register`). Each op carries a `WaveIndexMappingAttr` encoding element distribution across device/workgroup/workitem/register dimensions as `(offset, count, step)` triples.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Point to WaveOps.td and co., it should be able to parse documentation from there.

Comment thread water/CLAUDE.md Outdated
Comment on lines +39 to +47
| Pass | Purpose |
|---|---|
| `water-wave-detect-normal-forms` | Detect satisfied invariants |
| `water-wave-infer-types` | Shape inference via dataflow |
| `water-wave-infer-index-exprs` | Forward/backward index expression propagation |
| `water-wave-propagate-elements-per-thread` | Replace register tensors with vector types |
| `water-wave-resolve-distributed-allocations` | Map distributed shapes to concrete memref layouts |
| `lower-wave-to-mlir` | Lower to arith/math/vector/memref dialects |
| `lower-normalform-module` | Remove the normalform wrapper |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to point to the named pipeline in addition to this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

water-middle-end-lowering is mentioned above

Comment thread CLAUDE.md Outdated

### Gotchas
- **Always set `WAVE_CACHE_ON=0`** when testing code changes — stale cache entries hide the effect of edits: `WAVE_CACHE_ON=0 pytest ...`
- DCO sign-off required on commits: `git commit -s`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Comment thread CLAUDE.md Outdated
### Linting
```bash
mypy # type check wave_lang
pre-commit run --all-files # Black, Ruff, clang-format
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't necessarily want it to touch irrelevant files in a commit

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed --all-files

@tgymnich tgymnich force-pushed the tim/claude branch 2 times, most recently from ecb287e to c8a0d8e Compare April 8, 2026 10:14
tgymnich and others added 2 commits April 8, 2026 12:14
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Tim Gymnich <tim@gymni.ch>
- water/AGENTS.md: restructure Building section to clarify that Water
  must be built with CMake first, then pip install with WAVE_WATER_DIR;
  add full cmake configure/build commands and useful flags; note that
  ninja alone is sufficient for iterating after initial pip install;
  add git clang-format guidance; add lit location note; add Pipelines.cpp
  reference in Pass Pipeline section
- waveasm/AGENTS.md: add git clang-format guidance
- AGENTS.md: update pre-commit invocation; add AGENTS.local.md to .gitignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Tim Gymnich <tim@gymni.ch>
@tgymnich
Copy link
Copy Markdown
Contributor Author

tgymnich commented Apr 8, 2026

@willghatch

I have mixed feelings about checking in a CLAUDE.md or AGENTS.md file. I DO want to share pieces of it, but I also want to always be able to inject my own repo-local config without conflicting with checked-in files,

This should be even easier now, that the CLAUDE.local.md and AGENTS.local.md are in .gitignore, and as mentioned above claude is still reading these files and loads them into the context.

and I worry that over time the AGENTS.md check-in can become stale, or become large.

I share your concerns. Let's keep updating these files and keep them as small as possible. I am open to cutting the current set of files down even further. This is just a starting point.

I've personally been using a script that can pull in many snippets to build an AGENTS.md file, where I can add and remove default and non-default snippets, where some are global defaults (IE stuff about my workflow that I always use), some are per-project defaults, some non-default that I can manually trigger to add, etc (https://github.com/willghatch/dotfileswgh/blob/2331bbb8998668406b5f0d11e8c7b9fe3561a7ae/commands/agents-md-generate). I somewhat wish we would check in a directory of markdown files with instructions that we can pull in a la carte, but that's sort of an obtuse workflow if you're not using something like my script.

This sounds a lot like progressive disclosure. We could have a directory like: agent_docs/ containing those snippets. Then, in AGENTS.md file, we can include a list of files in this directory with a brief description, and instruct Claude to decide which (if any) to read.

I've been intending to make a skills directory and start contributing some skill files, which I think would be a great way to have re-usable instructions that don't always get loaded.

+1

Anyway, I'm not sure this comment even has something actionable about it. I'm just... unsatisfied with the AGENTS.md standard and the feeling that I'm going to get to a point where I am deleting the checked-in file with every checkout to replace it with my own, and then always having to deal with a file that git thinks is dirty, having to deal with it during rebasing, etc, and it always being a pain.

Isn't this already the case, that AGENTS.md would appear in unstaged changes?
You could use git update-index --skip-worktree AGENTS.md if you really wanted to ignore the repo AGENTS.md.

@willghatch
Copy link
Copy Markdown
Contributor

I didn't know about git update-index --skip-worktree, thanks!

@willghatch
Copy link
Copy Markdown
Contributor

willghatch commented Apr 8, 2026

Are you sure claude is still reading CLAUDE.local.md? I had read that it isn't. Also, I don't think Cursor Agent, Opencode, OpenAI Codex, Gemini CLI, etc, etc, read the AGENTS.local.md file. I don't want a workflow that only works for one agent program, I want to be able to keep using any/all of them. So I do want explicit instructions to load it in the main AGENTS.md file.

@willghatch
Copy link
Copy Markdown
Contributor

To be clear: I'm not asking for all of my grievances to be addressed before we move forward, I just want to put my thoughts and concerns out there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants