mcppls-contributing · git:20260922.d236148 · 2026-09-22 · sha256 bc4877f6d6541aba

mcppls-contributing git:20260922.d236148A

Immutable. This exact content never changes and is served at /api/v1/blob/bc4877f6d6541aba.

---
name: mcppls-contributing
description: Use when contributing to mcpp-language-server (mcppls) — building it, finding where code belongs, writing tests and conformance fixtures, keeping the specifications traceable, and what a change has to prove before it is submitted.
---

# Contributing to mcppls

## The shape of the repository

| Directory | What is in it |
|---|---|
| `src/` | The server. C++23 modules only, no headers, no macros. `src/<dir>/<name>.cppm` is `mcppls.<dir>.<name>` |
| `tests/` | Unit tests, one `test_<subject>.cpp` each, run by `mcpp test` |
| `modules/testing/` | The in-repo test harness package `mcppls.testing` that `tests/` depends on |
| `modules/os/` | Three platform-constant packages; one is chosen by the build target and used with `if constexpr` |
| `docs/specs/` | The five normative specifications, their schemas and examples |
| `conformance/` | Fixtures that drive a real server over LSP and check the answers |
| `tools/bench/` | Review fixtures with expected findings: precision and recall for the review rules |
| `editors/` | The VS Code extension and the coding-agent integrations |
| `packaging/` | How the shipped payload (server + clangd + semantic kit) is assembled |
| `tools/model-gateway/` | A separate package: the only thing that ever talks to a model endpoint |
| `vendor/` | Upstream data carried verbatim (the LSP meta model) |
| `docs/` | User documentation. `.agents/docs/design.md` is the design record — different audience |

## Build and prove it

```bash
mcpp build                               # and --target aarch64-macos / x86_64-windows-gnu
mcpp test                                # plus --profile release: release-only defects are real here
mcpp run -p devtools -- check all
python3 docs/specs/tools/validate.py          # needs jsonschema
```

Conformance needs a payload; `CONTRIBUTING.md` has the exact command and how to get one.

**What a change has to prove** depends on what it touches:

| Change | Prove it with |
|---|---|
| Server behaviour | A unit test, and a conformance fixture if an editor would see it |
| Anything about how a project is detected or planned | A conformance fixture — they drive the real LSP |
| A review rule | A `bench/review/` fixture with its expected findings |
| A specification | The text, its schema, its examples, the fixtures, and `conformance/traceability.json` together |

## Rules that are not negotiable

- **No headers, no macros in `src/`.** If something seems to need one, it is a design question, not
  a workaround.
- **Every normative rule in `docs/specs/` carries an identifier and evidence.** `validate.py` fails if a
  MUST/SHOULD has no identifier, or an identifier has no evidence, or the evidence names something
  that does not exist.
- **Nothing the server starts may be able to hold it.** External programs go through
  `mcppls.platform.toolrun`: own process unit, bounded reads, a deadline that ends the unit.
- **Runs the server starts are offline by default.** A fixture asserts it rather than trusting it.
- **The version lives in `mcpp.toml`** and is written everywhere else by
  `mcpp run -p devtools -- version --set`, never by hand.

## Commit messages

Lowercase `type(scope): a sentence that says what is now true`, not an imperative. The body is
prose: what failed, what changed, why. For example:

```
fix(platform): the bound ends the unit even when the tool itself went quietly
feat(model): the cache is a model, per source and fingerprinted, and clangd is never started without a database
```

`git log --oneline -40` is the convention; match it.

## Submitting

Open an issue first for anything beyond a fix. Fork, branch, and make CI pass — all of it, on
Linux, macOS and Windows. A pull request with failing CI is not reviewed.