[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6BZEQWTYZ80A2BZ7YPMEC33":3,"skill-same:01M6BZEQWTYZ80A2BZ7YPMEC33":66},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":46,"repositoryHtmlUrl":47,"repositoryHomepageUrl":48,"ownerHtmlUrl":49,"ownerBlogUrl":50,"ownerDescription":6,"updatedAt":51,"install":52,"resources":65},"01M6BZEQWTYZ80A2BZ7YPMEC33","cpp-style",null,"Read before writing, modifying or reviewing any C++ code — redundancy (the rule we care most about), modules and files, errors and defense, async, logging, naming, words, templates, API preferences.","clice-io\u002Fclice","clice-io","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F176553789?v=4","01M6BZEJH3SKDZ3SMSS1V6CKKB","clice","01M6BZEJN97S3AQVRQ4V7GGE5C",1381,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fclice-io\u002Fclice\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcpp-style\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"cpp","style","cpp style","modules","errors","rule","read","about","naming","files","async","c++","templates","logging","api","code","writing","preferences","defense","2026-11-10 10:12:30",false,"---\nname: cpp-style\ndescription: Read before writing, modifying or reviewing any C++ code — redundancy (the rule we care most about), modules and files, errors and defense, async, logging, naming, words, templates, API preferences.\n---\n\n# clice C++ Coding Style\n\n## Redundancy Is a Defect\n\nThis is the convention we care most about. Redundant code is not a style\nnit — it actively misleads: every guard implies the guarded state can\noccur, every branch implies it can be taken, every parameter implies a\ncaller needs it. When that implication is false, the reader wastes time\ndefending against ghosts.\n\n- **Every branch must be reachable.** Before adding a guard or fallback,\n  prove the state can actually occur — construct the input that hits it.\n  If you can't, don't write it.\n- **No speculative generality.** No parameters, options, hooks, or\n  abstraction layers for hypothetical future callers. Add them when the\n  second real caller arrives.\n- **One way to do each thing.** Don't leave an old path alive next to its\n  replacement \"just in case\" — migrate all callers and delete it in the\n  same change.\n- **Re-read after every change.** Edits leave residue: conditions that\n  became constant, variables read once, branches that now collapse,\n  `else` after `return`, a helper with one remaining caller. Fold them\n  before you're done — simplification that removes a concept beats one\n  that merely shortens lines.\n- **Delete, don't comment out.** Git history is the archive.\n- **One behavior difference is one options field.** Two behaviors of the\n  same logic are selected by a boolean in an options struct\n  (`SemanticsOptions{.all_files = true}`), not by a subclass, a dummy\n  collaborator, or a parallel code path.\n- **Cross-cutting invariants get a single writer.** Accounting, budgets,\n  ownership and visibility guarantees live in one type whose methods are the\n  only transitions and whose doc comment lists the invariants; before coding,\n  grep every site the invariant touches and funnel them through one helper\n  so a missing site is discoverable. Per-site patches never catch up with a\n  reviewer who re-derives the invariant from the whole diff.\n\n## Files & Organization\n\n- clice is one C++20 module, `clice`. An interface is a partition,\n  `\u003Cstem>.cppm` beside its source, named after its layer and then what it\n  is — usually its path under `src\u002F` (`module clice:vfs.path;`,\n  `unittests.*` under `unittests\u002F`); `pixi run check-layers` checks the\n  layer. A part grown into a directory keeps its interface there under the\n  part's own name (`feature\u002Fhover\u002Fhover.cppm` is `feature.hover`), beside\n  its implementation units and the internal partitions they share\n  (`feature.hover.card`). Sources are implementation units `.cpp`, entry\n  points `.cc` (`clice.cc`, `src\u002Fdriver\u002F*.cc`).\n- A module unit opens with its module declaration, then one\n  `import :\u003Cpartition>;` per partition it names. The partition\n  `:support.prelude` imports `std.compat`, the C library's names past it\n  (`libc`) and the third-party module (`modules\u002F`), and gives the namespaces\n  clice writes their short names in `clice` — `ranges`, `views`, `chrono`,\n  `this_thread`, `ipc`, `lsp`, `protocol`, `codec`, `json`, `fs`, `sys`,\n  `async`, `cli`, `meta`, `zest`. The primary interface\n  (`src\u002Fmodule.cppm`) re-exports it, which brings it to every implementation\n  unit; every partition imports it. Code inside `clice` writes those names\n  (`ranges::sort`, `protocol::Range`, `async::task`), never `std::ranges::`\n  or `kotatsu::ipc::protocol::`, and no file declares them again.\n- No module carries a macro: every compilation force-includes\n  `support\u002Fmacros.h`, which holds clice's own after including the\n  libraries' (`modules\u002Fmacros.h`). A unit opens a global module fragment\n  (`module;`) only for a header no module carries, a platform header.\n- `.h` is left for what a module cannot carry — macros (`support\u002Fmacros.h`)\n  and platform headers — with `#pragma once`, never include guards.\n- File names are `snake_case`.\n- Every file sees the names of all it imports: a file-local helper can\n  clash with a name of another partition or lose overload resolution and\n  ADL to a library function (`llvm::join`) no header used to bring in.\n- File-local helpers: a single one is `static`; a cluster of them goes in\n  one anonymous namespace.\n\n## Data & Types\n\n- `struct` by default, even for types with methods. `class` only when\n  there is a real invariant that private access protects.\n- `enum class` with an explicit underlying type (e.g. `: std::uint8_t`);\n  document each enumerator with `\u002F\u002F\u002F` when its meaning is not obvious.\n- Prefer designated initializers (`{.field = value}`) for aggregate\n  construction.\n- West const: `const T&`, never `T const&`.\n- A class lays out its public members first, then its private member\n  functions under one `private:`, then its data members under a second\n  `private:` — functions and fields never interleave. Data members stand\n  one blank line apart, each one's comment on the lines above it, never\n  trailing it.\n\n## Errors, Exceptions & Defense\n\n- The project builds with `-fno-exceptions -fno-rtti`: no\n  `throw`\u002F`try`\u002F`catch`, no `dynamic_cast`\u002F`typeid`. Polymorphic\n  inspection uses `llvm::isa\u003C>` \u002F `cast\u003C>` \u002F `dyn_cast\u003C>`.\n- Fallible synchronous operations return `std::expected\u003CT, E>` with `E` =\n  `std::string` or `std::error_code`; async code uses kotatsu's outcome\n  types. `llvm::Error` only where an LLVM API forces it.\n- `assert` pins preconditions; impossible branches end in\n  `std::unreachable()` — never `llvm_unreachable` (project convention).\n- Invalid external input (broken source code, malformed requests)\n  degrades gracefully — empty result, input passed through — it never\n  crashes the server. But graceful degradation is not scattered null\n  checks: per the redundancy rule, defend only against states that can\n  occur. The Debug (ASan + assertions) test surface is the safety net.\n- A gap a real workflow can reach that the maintainer accepted rather\n  than fixed lives in the code, not on the board: `\u002F\u002F LIMITATION:` where a\n  fix would go, saying what goes wrong and who reaches it. `FIXME` is for\n  what is still to be fixed. When a user hits a limitation, it becomes an\n  issue again.\n\n## Error Handling (control flow)\n\n- Scope an error variable with an `if` init-statement when nothing after\n  the `if` needs it: `if (auto result = foo(); !result.has_value())`.\n- A type with `operator bool` needs no condition: `if (auto err = foo())`,\n  never `if (auto err = foo(); err)`.\n- When the success path needs the variable, declare it as a plain local\n  and return early on the error — never an init-statement that forces the\n  success path into an `else`.\n\n## Concurrency & Async\n\n- Async code is kotatsu coroutines (`async::task`, `co_await`) — no callback\n  style. A public interface may stay synchronous and drive a coroutine\n  internally when the caller has no event loop (see `Toolchain`).\n- Review coroutine code by interleavings, not function by function: list\n  every `co_await` suspension point, the events that can fire while it is\n  suspended (crash, respawn, dispatch, cancellation, another coroutine\n  resuming), and trace the shared state through each chain; then check that\n  what the frame captured before suspending is still valid when it resumes.\n  Bugs here are always cross-function interleavings; a function-level read\n  finds none of them.\n- Cancellation flows down the ownership tree through `task_group::cancel()`;\n  tokens and sources exist only to cross an ownership boundary — the serve\n  mode shutdown source in `MasterServer`, the batch commands' in\n  `Lifetime` (`driver\u002Frun.cppm`). Graceful shutdown is not\n  cancellation — kotatsu has no shield, a cancel cascades all the way down — so\n  a shutdown is a cancellable serving phase bounded by `with_token`, then a\n  non-cancellable drain that joins each task in order.\n- `cancellation_token::wait()` completes by cancelling itself. Awaited\n  directly inside `when_any` it propagates that cancellation into the parent\n  frame and skips everything after the `co_await`; wrap it in `with_token`\n  (which catches internally) or add `.catch_cancel()`.\n\n## Logging\n\n- Log through the `LOG_TRACE` \u002F `LOG_DEBUG` \u002F `LOG_INFO` \u002F `LOG_WARN` \u002F\n  `LOG_ERROR` macros (`std::format` syntax, source location captured\n  automatically); `LOG_FATAL` logs and aborts, `LOG_ANOMALY` and\n  `LOG_GUIDANCE` are the bug and user-setup channels (all in\n  `support\u002Fmacros.h`). Never write to the outputs of\n  `support\u002Flogging` directly, never print\n  diagnostics to stdout\u002Fstderr.\n\n## Naming Conventions\n\n- **Variables, member fields, function names**: `snake_case`. Class member fields do NOT use any special suffix\u002Fprefix (no trailing `_`, no `m_` prefix).\n- **Class names, template parameter names, enum names**: `PascalCase`. Exception: some class names also use `snake_case` — follow the existing style in the project.\n- **Enum values**: `PascalCase`.\n- **Acronyms stay uppercase in type names**: `PCHState`, `LSPClient`, `TUIndex` — never `PchState`, `LspClient`.\n- **A file-local type is named by its role in the file**, without the\n  words of the file's own subject: in an anonymous namespace,\n  `FoldingRangeCollector` in `folding_ranges.cpp` is `Builder`, `ScanOptions`\n  in `scan.cc` is `Options`. A type that is the file's subject itself keeps\n  its name (`Lexer` in `lexer.cpp`).\n- **Nothing is a `Collector`**: the type producing the file's answer is a\n  `Builder`; a visitor gathering nodes is a `\u003CWhat>Finder`\n  (`PackForwardFinder`), or is named by what it gathers (`SpelledNames`); a\n  clang callback that only records what clang reports is a `\u003CWhat>Recorder`\n  (`CompilationUnit::DiagnosticRecorder`).\n- **Overloads, not prefixes, tell one job's variants apart**: every\n  conversion to the LSP form is a `to_protocol` overload (a second form of\n  the same input is named by the form: `to_symbol_information`), and a feature's\n  answer from the index is an overload of its answer from the AST\n  (`semantic_tokens(SourceText&, …)` beside `semantic_tokens(CompilationUnit&,\n…)`) — never `semantic_tokens_to_protocol` or `index_semantic_tokens`.\n- Doc comments on declarations use `\u002F\u002F\u002F`; the bar for when to write a\n  comment at all is in CLAUDE.md.\n\n## Words to Use and Avoid\n\nIdentifiers and comments use plain words: the word a newcomer would guess\nfor the thing, not a metaphor or a rare word that needs a glossary\n(verdict, envelope, ledger). One word means one thing across the codebase —\nbefore naming, grep whether the word already means something else nearby,\nand don't split one concept over two words. A name that its own doc comment\nhas to correct is the wrong name.\n\nThese were renamed out of the codebase; don't bring them back:\n\n| Avoid                                                                                               | Say instead                                                                                                                                                                                                                                                         |\n| --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| row \u002F rows                                                                                          | an index record: `occurrence` \u002F `relation`, else `entry`; a file's whole index data: `index` \u002F `shard` \u002F `variant`; a source line: `line`                                                                                                                           |\n| verdict                                                                                             | `result` \u002F `decision`, whichever the site is                                                                                                                                                                                                                        |\n| claim                                                                                               | one word per site: `take`, `acquire`, `reserve`, `cover`, `report`                                                                                                                                                                                                  |\n| envelope                                                                                            | what it is: `TUIndexBlob`, the TU index, a container, a header                                                                                                                                                                                                      |\n| ledger                                                                                              | `table` \u002F `list`                                                                                                                                                                                                                                                    |\n| wire (the serialized form)                                                                          | `serialized` \u002F `encoded`; \"in the protocol\" for IPC                                                                                                                                                                                                                 |\n| settle                                                                                              | `finish` \u002F `become idle`                                                                                                                                                                                                                                            |\n| flavor                                                                                              | `kind` \u002F `variant`                                                                                                                                                                                                                                                  |\n| land \u002F landing (a result arriving)                                                                  | `commit` \u002F `merge` \u002F `finish`                                                                                                                                                                                                                                       |\n| sweep                                                                                               | `pass` \u002F `run` \u002F `scan`; for cleanup, `remove`                                                                                                                                                                                                                      |\n| tier (an encoding choice)                                                                           | `encoding` (`MaskEncoding`); the search ranking's `NameRank::tier` stays                                                                                                                                                                                            |\n| surface (verb), vouch for                                                                           | `report` \u002F `show`, `guarantee` \u002F `confirm`                                                                                                                                                                                                                          |\n| stamp outside `vfs`                                                                                 | `version` \u002F `generation`                                                                                                                                                                                                                                            |\n| collector                                                                                           | `Builder` \u002F `\u003CWhat>Finder` \u002F `\u003CWhat>Recorder` (see Naming Conventions)                                                                                                                                                                                              |\n| `Features`, `Requests` (the server's request entry points)                                          | the request's handler in `LSPClient` (`server\u002Fclient`), routed by its served project (`ServedProject::pick_route`); the features are `src\u002Ffeature`'s                                                                                                                |\n| projection                                                                                          | what it is: a document's latest compile (`DocumentCompile`), a result computed from the index (the `SourceText` overloads of `semantic_tokens`), the LSP form; only the indexer's step from the semantic map to entries is a projection (`project_node`)            |\n| `switch_source_header` (the feature)                                                                | `counterparts`: the files a file pairs with; only the editor command keeps the action's name (`clice.switchSourceHeader`)                                                                                                                                           |\n| quarantine, barred                                                                                  | the document's crash records (`Session`'s, one `FailureRecord` per request kind); a record `stops` its operation                                                                                                                                                    |\n| strikes                                                                                             | the failure count (`FailureRecord::count`)                                                                                                                                                                                                                          |\n| license (to retry)                                                                                  | the retry a change or a save allows; the `Attempt` holding it                                                                                                                                                                                                       |\n| overtaken (an attempt)                                                                              | `crashed_meanwhile`; a task-graph attempt overtaken by new content keeps the word                                                                                                                                                                                   |\n| parked (crash records)                                                                              | nothing: the records live in the document's `Session` and end with it; a reply a test hook holds, or a waiter on an event, is still parked                                                                                                                          |\n| `BlameBudget`, blaming a PCH pair                                                                   | a failure of its consumption (`pch_consume_failed`), a record with a cooldown policy                                                                                                                                                                                |\n| evidence (kind)                                                                                     | `feature::RequestKind`                                                                                                                                                                                                                                              |\n| ticket (outside a request)                                                                          | a sequence number (`ReindexQueue`'s `seq`); `Ticket` is a request's hold on its buffer                                                                                                                                                                              |\n| superseded (a blob)                                                                                 | `previous`                                                                                                                                                                                                                                                          |\n| `PCHFamily`, `PCMFamily`, `PCHBuilder`, `PCMBuilder`, builder (of PCHs, modules)                    | the PCH and PCM work (`Project::pch_work`, `Project::module_work`) in `project\u002Fgraph\u002Fpch`, `project\u002Fgraph\u002Fpcm`; what both share is `project\u002Fgraph\u002Fprecompiled`                                                                                                      |\n| `TURunFamily`, TU run, unit run                                                                     | a unit's compile (`Project::compile_unit`, `UnitRequest`, `UnitResult`, `NodeKind::Unit`)                                                                                                                                                                           |\n| round (of a graph node, of the background index), `RoundContext`, `RoundOutcome`                    | a graph node's attempt (`Attempt`, `AttemptState`, `Result`); the background index's sweep over its queue is a pass (`BackgroundIndex::run_pass`); round-trip and rounding keep the word                                                                            |\n| outcome                                                                                             | `result`, or the more exact word (`CompileStatus`, `CompilationUnit::status`); kotatsu's `outcome` types keep their name                                                                                                                                            |\n| lend, lent, lender, lending (a command)                                                             | the borrowing side's words: the unit a command is borrowed from (`Candidate::from`, `borrowed_command`), the unit whose command a file borrows; a host's command a header compiles under is the host's                                                              |\n| `Inferred` (a command source)                                                                       | `CommandSource::Borrowed`                                                                                                                                                                                                                                           |\n| `IndexPump`, pump, engine (of the index)                                                            | the background index (`BackgroundIndex`, `BackgroundIndex::run_pass`)                                                                                                                                                                                               |\n| `SchedulingStack`, scheduling stack                                                                 | the project: it builds with the event loop and worker pool its owner gives it (`Project::loop`, `Project::pool`)                                                                                                                                                    |\n| `CommandResolver`                                                                                   | command resolution, members of `Project` (`project\u002Fcommand\u002Fresolve`: `resolve_command`, `command_identity`)                                                                                                                                                         |\n| `PendingTable`, pending table                                                                       | `ReindexQueue`: the background index's queue with each unit's reason                                                                                                                                                                                                |\n| `TakenDebt`, debt (a reindex owed)                                                                  | `TakenReindex`, a reindex                                                                                                                                                                                                                                           |\n| `CommandSnapshot`, command snapshot, `BuildSnapshot`, `SavedListings`, listings                     | `SavedMembers` (blob kind `Members`): which databases listed each file, and the provisional members; a unit's command is its index's `indexed_command`                                                                                                              |\n| `ServingSide`, serving side (the project asking the server)                                         | nothing: the project calls no server; it emits signals (`BackgroundIndex::on_attempt_finished`, `Project::on_index_changed`, `Project::on_metadata_changed`) and its owner hands it the open documents as data (`OpenFile`)                                         |\n| `LiveSources`, `OpenDocuments`, `PeerQueries`, peers (other projects' queries)                      | `IndexQuery`: the open documents its owner hands it (`OpenBuffer`, `IndexQuery::reading`), the other projects it asks (`IndexQuery::asking`, `asked`, `gather`)                                                                                                     |\n| `indexer\u002F` (the background index's directory)                                                       | `project\u002Fbackground\u002F`; `index\u002Findexing` is the indexer that builds a TU's index                                                                                                                                                                                     |\n| `IncludeEdge` (the index's), `include_edges`; `IncludeTree` (analysis')                             | `ResolvedInclude`, `resolved_includes`; `ScopedIncludeTree`; `syntax::IncludeEdge` and `index::IncludeTree` keep theirs                                                                                                                                             |\n| family (of graph nodes)                                                                             | kind (`NodeKind`)                                                                                                                                                                                                                                                   |\n| artifact (a PCH or PCM)                                                                             | precompiled (`Precompiled`, the PCH and PCM records; the blob key `artifacts` stays: persisted)                                                                                                                                                                     |\n| superseded (a unit's index), `mark_behind`                                                          | outdated, `mark_outdated`                                                                                                                                                                                                                                           |\n| sentinel (the graph's node for an import no module provides)                                        | unresolved import (`unresolved_import`)                                                                                                                                                                                                                             |\n| retire, retirement (a unit leaving the build)                                                       | dropped: the build stopped compiling it (`Project::update_members`)                                                                                                                                                                                                 |\n| enterings                                                                                           | `include_chains`: every place a unit's compile enters a header, by its include tree                                                                                                                                                                                 |\n| probe (a header compiled alone, a `__has_include` lookup)                                           | the self-containment check; a `__has_include` `check`                                                                                                                                                                                                               |\n| header mode, `HeaderMode`                                                                           | the self-containment check's result (`SelfContainment`, `Hosting::self_containment`)                                                                                                                                                                                |\n| trial (a header compiled alone)                                                                     | the self-containment check (`SelfContainment`); the precompiled records' `trials` key keeps its spelling                                                                                                                                                            |\n| `HostTree`                                                                                          | `PreprocessedTree` (`Hosting::trees`)                                                                                                                                                                                                                               |\n| lexical chain (the chain a header's context is cut along)                                           | nothing: a chain comes from the host's include tree; the lexical scan only finds the candidate hosts                                                                                                                                                                |\n| standalone header (indexed on its own)                                                              | nothing: only the project's units are indexed, a header through the units reading it                                                                                                                                                                                |\n| workspace (one project or its root)                                                                 | `project`, `project root` (`Settings::project_root`); \"workspace\" is only what the editor opens, its folders; the `--workspace` flag and `${workspace}` in clice.toml keep their spelling                                                                           |\n| `IndexReader`, `ProjectReader`, bootstrap, loading a project                                        | `Project::open` with its `OpenOptions`; a `Project` owns the read side of its index (`index_query`, `freshness`), and a command-line run reads through the `OpenedProject` the driver opens                                                                         |\n| heir, retire (a project), weigh (the databases)                                                     | `successor`, `stop`, `reload_databases`                                                                                                                                                                                                                             |\n| `Selection`, pin, pinned (a context)                                                                | `ContextChoice`, \"choice\" in prose; a choice that stops holding stays `inactive` (`MasterServer::ChoiceEntry`)                                                                                                                                                      |\n| `ProjectServer`                                                                                     | `ServedProject`                                                                                                                                                                                                                                                     |\n| `ASTFamily`, `Dispatcher`, `Invalidator`, `FileTracker`, `EditorContext`                            | what the served project does, in its files: compiling the open documents (`compile.cpp`), what their diagnostics show (`diagnostics.cpp`), answering and asking the workers (`answer.cpp`), handling changes (`changes.cpp`), their commands (`served_project.cpp`) |\n| `Config`, config (what clice.toml holds)                                                            | `Settings` (`load_settings`, `project.settings`); \"configuration\" is only the build configuration a rule's tag names (debug, release), and \"configuration file\" the clice.toml that holds the settings                                                              |\n| epoch (a document's compile), `mark_not_current`                                                    | the AST node's generation (`TaskGraph::generation`): a compile is current while the one it ran at (`DocumentCompile::generation`) is the node's (`ServedProject::current`)                                                                                          |\n| a worker's own LRU, `max_documents`, `document_unloaded`, `EvictedParams`; the pool's `owner` table | the pool's residency (`Residency`: a document's assignment, its AST resident or not, `WorkerPool::resident`, `max_resident`); a worker evicts only when told (`EvictParams`)                                                                                        |\n| hand over (an index)                                                                                | `send_index`                                                                                                                                                                                                                                                        |\n| `ServingMode` (`IndexOnly`, `Escalated`), escalate, escalation, investment (in an open document)    | whether the document is compiled (`ServedDocument::compiles`), from now on (`ServedProject::start_compiling`); otherwise only the index answers it                                                                                                                  |\n| `full_lex`, `await_cold_attempt` (what a request asks of routing)                                   | `RouteOptions::lexes_whole_buffer`, `waits_for_index`; `needs_ast`                                                                                                                                                                                                  |\n| `MasterServer::route`, `reroute`, routing a file to a project                                       | the project a file belongs to: `MasterServer::pick_owner`, `update_owners`; a route is only what answers a request (`pick_route`, `Route`)                                                                                                                          |\n| `uri_to_path`                                                                                       | `feature::to_path`, beside `feature::to_uri`                                                                                                                                                                                                                        |\n| retire, retiring (a worker slot)                                                                    | a scale-down (`scheduler::ScaleDown`, `WorkerPool::scale_down_worker`, `scaling_down`, `SlotState::ScaledDown`)                                                                                                                                                     |\n| `Dead` (a worker slot)                                                                              | `GivenUp`: its crash budget ran out, and only its revival brings it back                                                                                                                                                                                            |\n| `foreground_pulse`                                                                                  | `WorkerPool::user_activity`, as the scheduler's                                                                                                                                                                                                                     |\n| `BuildProbe`, probe (test instrumentation)                                                          | the test hooks: `TestHooks` (`worker\u002Ftest_hooks`), the server's test-only requests in `server\u002Ftest_hooks.cppm`                                                                                                                                                      |\n| culprit, blame (a worker death)                                                                     | the requests a death names (`WorkerDeath::named`); a request charged with a death                                                                                                                                                                                   |\n| preempted (a worker the pool killed)                                                                | `killed_on_purpose`; preempt is the scheduler asking a request to stop                                                                                                                                                                                              |\n| `WorkerCrashInfo`, `on_crash` (the pool's callback)                                                 | nothing: tests read the slot, the user is told by guidance when every worker of a kind is given up; kotatsu's `sys::on_crash` keeps its name                                                                                                                        |\n| `ScopedTimer`, `ms_f`                                                                               | `Timer`, `Timer::precise_ms`                                                                                                                                                                                                                                        |\n| `print_argv`, `host_quoting`                                                                        | `join_command`; `sys::cmd::native_quoting`                                                                                                                                                                                                                          |\n\nDomain words with one meaning each — use them only in that meaning:\n\n- **spelling**: how a path is written — the anchored absolute path,\n  `..` kept, handed only to the identity functions or to clang.\n- **host**: the source file whose compile context a header borrows.\n- **slot**: one worker's place in the worker pool.\n- **stamp**: in `vfs` only, a file's change fingerprint (size + mtime +\n  ctime).\n\n## Templates, Type Traits & Concepts\n\n- `std::remove_cvref_t\u003CT>` only where `T` can be deduced as a reference:\n  a forwarding reference `T&&`. `T`, `T&` and `const T&` parameters,\n  class template parameters and return types never deduce one.\n- A type trait is a variable template specialized directly\n  (`template\u003C> inline constexpr bool is_my_type_v\u003CMyType> = true;`), never\n  a variable template wrapping a class template's `::value`.\n- A concept over a trait uses `T` as is (`concept MyTrait = is_my_type_v\u003CT>;`)\n  unless it deliberately sees through references and cv-qualifiers; the\n  caller passes the right type.\n\n## String Literals\n\n- Prefer C++11 raw string literals `R\"(...)\"` over escaped strings. Avoid `\\\"`, `\\\\`, `\\n` in string literals when a raw literal is cleaner.\n\n## Style\n\n- Definitions stand one blank line apart, which clang-format leaves to the\n  writer, so that a `KANNOTATE_TYPE` sits directly above the type it\n  annotates, the type's doc comment above both.\n- Prefer `[[maybe_unused]]` over `(void)` for intentionally unused variables or parameters.\n- Arithmetic counters step with `x += 1` \u002F `x -= 1`, in `for` heads too — never `++`\u002F`--`; split fused forms like `if(++x > n)` into two statements. Iterators and other types without `+=` are exempt. This applies to code you write or touch, not as a repository-wide sweep.\n\n## Modern C++ Usage\n\n- Use C++20\u002F23 APIs whenever possible. Do NOT use `\u003Ciostream>` facilities (`std::cout`, `std::cin`, `std::cerr`, etc.). Also do NOT use C-style I\u002FO (`printf`, `fprintf`, etc.).\n- Prefer `ranges` \u002F `views` APIs over raw loops and traditional `\u003Calgorithm>` calls.\n- Range helpers come from the standard library, never LLVM's `STLExtras`: `ranges::contains` not `llvm::is_contained` (a set or map uses its own `.contains()`), `ranges::any_of` \u002F `find_if` \u002F `sort` not `llvm::`'s, `views::enumerate` \u002F `zip` \u002F `reverse` \u002F `transform` not `llvm::enumerate` \u002F `zip` \u002F `reverse` \u002F `map_range`. Only `llvm::concat` (C++26 in the standard) and `llvm::interleave` stay.\n- Prefer LLVM's efficient data structures (e.g., `llvm::SmallVector`, `llvm::DenseMap`, `llvm::StringMap`, `llvm::StringRef`) over their `std` counterparts when appropriate.\n- The operating system is reached through kotatsu: paths, files and directories through `fs` (`kotatsu::fs`), the environment, programs and processes through `sys` (`kotatsu::sys`), never `llvm::sys` or `std::filesystem`. LLVM stays where an interface takes its types — `llvm::vfs` for clang's file manager, a `llvm::MemoryBuffer` clang or the index adopts, filled from an `fs::File`. Crashes are `sys::on_crash`'s and the trace `sys::write_stacktrace`'s, never LLVM's signal handling: clang's outputs are not registered for removal on a crash, which would install LLVM's handlers over them.\n- Where a token is, which file holds it and what comes before it are the compile's questions: code holding a `CompilationUnit` asks it (`written_at` \u002F `seen_at` \u002F `produced_at`, the ranges, `before`, `expansion_level`, the tokens), never clang's `SourceManager`, whose answers miss what the unit maps (the PCH's copy of the focus file, the NUL at a completion's point). Each member's doc comment is its contract and a unit test holds it to it; a question the unit lacks is added there, with both. Helpers handed only a `Decl` or an `ASTContext` keep clang's.\n\n## Parameter Passing Preferences\n\n- For string parameters, prefer `llvm::StringRef` > `std::string_view` > `const std::string&`.\n- For array\u002Fspan parameters, prefer `llvm::ArrayRef` > `std::span` > `const std::vector&`.\n","# clice C++ Coding Style\n\n## Redundancy Is a Defect\n\nThis is the convention we care most about. Redundant code is not a style\nnit — it actively misleads: every guard implies the guarded state can\noccur, every branch implies it can be taken, every parameter implies a\ncaller needs it. When that implication is false, the reader wastes time\ndefending against ghosts.\n\n- **Every branch must be reachable.** Before adding a guard or fallback,\n  prove the state can actually occur — construct the input that hits it.\n  If you can't, don't write it.\n- **No speculative generality.** No parameters, options, hooks, or\n  abstraction layers for hypothetical future callers. Add them when the\n  second real caller arrives.\n- **One way to do each thing.** Don't leave an old path alive next to its\n  replacement \"just in case\" — migrate all callers and delete it in the\n  same change.\n- **Re-read after every change.** Edits leave residue: conditions that\n  became constant, variables read once, branches that now collapse,\n  `else` after `return`, a helper with one remaining caller. Fold them\n  before you're done — simplification that removes a concept beats one\n  that merely shortens lines.\n- **Delete, don't comment out.** Git history is the archive.\n- **One behavior difference is one options field.** Two behaviors of the\n  same logic are selected by a boolean in an options struct\n  (`SemanticsOptions{.all_files = true}`), not by a subclass, a dummy\n  collaborator, or a parallel code path.\n- **Cross-cutting invariants get a single writer.** Accounting, budgets,\n  ownership and visibility guarantees live in one type whose methods are the\n  only transitions and whose doc comment lists the invariants; before coding,\n  grep every site the invariant touches and funnel them through one helper\n  so a missing site is discoverable. Per-site patches never catch up with a\n  reviewer who re-derives the invariant from the whole diff.\n\n## Files & Organization\n\n- clice is one C++20 module, `clice`. An interface is a partition,\n  `\u003Cstem>.cppm` beside its source, named after its layer and then what it\n  is — usually its path under `src\u002F` (`module clice:vfs.path;`,\n  `unittests.*` under `unittests\u002F`); `pixi run check-layers` checks the\n  layer. A part grown into a directory keeps its interface there under the\n  part's own name (`feature\u002Fhover\u002Fhover.cppm` is `feature.hover`), beside\n  its implementation units and the internal partitions they share\n  (`feature.hover.card`). Sources are implementation units `.cpp`, entry\n  points `.cc` (`clice.cc`, `src\u002Fdriver\u002F*.cc`).\n- A module unit opens with its module declaration, then one\n  `import :\u003Cpartition>;` per partition it names. The partition\n  `:support.prelude` imports `std.compat`, the C library's names past it\n  (`libc`) and the third-party module (`modules\u002F`), and gives the namespaces\n  clice writes their short names in `clice` — `ranges`, `views`, `chrono`,\n  `this_thread`, `ipc`, `lsp`, `protocol`, `codec`, `json`, `fs`, `sys`,\n  `async`, `cli`, `meta`, `zest`. The primary interface\n  (`src\u002Fmodule.cppm`) re-exports it, which brings it to every implementation\n  unit; every partition imports it. Code inside `clice` writes those names\n  (`ranges::sort`, `protocol::Range`, `async::task`), never `std::ranges::`\n  or `kotatsu::ipc::protocol::`, and no file declares them again.\n- No module carries a macro: every compilation force-includes\n  `support\u002Fmacros.h`, which holds clice's own after including the\n  libraries' (`modules\u002Fmacros.h`). A unit opens a global module fragment\n  (`module;`) only for a header no module carries, a platform header.\n- `.h` is left for what a module cannot carry — macros (`support\u002Fmacros.h`)\n  and platform headers — with `#pragma once`, never include guards.\n- File names are `snake_case`.\n- Every file sees the names of all it imports: a file-local helper can\n  clash with a name of another partition or lose overload resolution and\n  ADL to a library function (`llvm::join`) no header used to bring in.\n- File-local helpers: a single one is `static`; a cluster of them goes in\n  one anonymous namespace.\n\n## Data & Types\n\n- `struct` by default, even for types with methods. `class` only when\n  there is a real invariant that private access protects.\n- `enum class` with an explicit underlying type (e.g. `: std::uint8_t`);\n  document each enumerator with `\u002F\u002F\u002F` when its meaning is not obvious.\n- Prefer designated initializers (`{.field = value}`) for aggregate\n  construction.\n- West const: `const T&`, never `T const&`.\n- A class lays out its public members first, then its private member\n  functions under one `private:`, then its data members under a second\n  `private:` — functions and fields never interleave. Data members stand\n  one blank line apart, each one's comment on the lines above it, never\n  trailing it.\n\n## Errors, Exceptions & Defense\n\n- The project builds with `-fno-exceptions -fno-rtti`: no\n  `throw`\u002F`try`\u002F`catch`, no `dynamic_cast`\u002F`typeid`. Polymorphic\n  inspection uses `llvm::isa\u003C>` \u002F `cast\u003C>` \u002F `dyn_cast\u003C>`.\n- Fallible synchronous operations return `std::expected\u003CT, E>` with `E` =\n  `std::string` or `std::error_code`; async code uses kotatsu's outcome\n  types. `llvm::Error` only where an LLVM API forces it.\n- `assert` pins preconditions; impossible branches end in\n  `std::unreachable()` — never `llvm_unreachable` (project convention).\n- Invalid external input (broken source code, malformed requests)\n  degrades gracefully — empty result, input passed through — it never\n  crashes the server. But graceful degradation is not scattered null\n  checks: per the redundancy rule, defend only against states that can\n  occur. The Debug (ASan + assertions) test surface is the safety net.\n- A gap a real workflow can reach that the maintainer accepted rather\n  than fixed lives in the code, not on the board: `\u002F\u002F LIMITATION:` where a\n  fix would go, saying what goes wrong and who reaches it. `FIXME` is for\n  what is still to be fixed. When a user hits a limitation, it becomes an\n  issue again.\n\n## Error Handling (control flow)\n\n- Scope an error variable with an `if` init-statement when nothing after\n  the `if` needs it: `if (auto result = foo(); !result.has_value())`.\n- A type with `operator bool` needs no condition: `if (auto err = foo())`,\n  never `if (auto err = foo(); err)`.\n- When the success path needs the variable, declare it as a plain local\n  and return early on the error — never an init-statement that forces the\n  success path into an `else`.\n\n## Concurrency & Async\n\n- Async code is kotatsu coroutines (`async::task`, `co_await`) — no callback\n  style. A public interface may stay synchronous and drive a coroutine\n  internally when the caller has no event loop (see `Toolchain`).\n- Review coroutine code by interleavings, not function by function: list\n  every `co_await` suspension point, the events that can fire while it is\n  suspended (crash, respawn, dispatch, cancellation, another coroutine\n  resuming), and trace the shared state through each chain; then check that\n  what the frame captured before suspending is still valid when it resumes.\n  Bugs here are always cross-function interleavings; a function-level read\n  finds none of them.\n- Cancellation flows down the ownership tree through `task_group::cancel()`;\n  tokens and sources exist only to cross an ownership boundary — the serve\n  mode shutdown source in `MasterServer`, the batch commands' in\n  `Lifetime` (`driver\u002Frun.cppm`). Graceful shutdown is not\n  cancellation — kotatsu has no shield, a cancel cascades all the way down — so\n  a shutdown is a cancellable serving phase bounded by `with_token`, then a\n  non-cancellable drain that joins each task in order.\n- `cancellation_token::wait()` completes by cancelling itself. Awaited\n  directly inside `when_any` it propagates that cancellation into the parent\n  frame and skips everything after the `co_await`; wrap it in `with_token`\n  (which catches internally) or add `.catch_cancel()`.\n\n## Logging\n\n- Log through the `LOG_TRACE` \u002F `LOG_DEBUG` \u002F `LOG_INFO` \u002F `LOG_WARN` \u002F\n  `LOG_ERROR` macros (`std::format` syntax, source location captured\n  automatically); `LOG_FATAL` logs and aborts, `LOG_ANOMALY` and\n  `LOG_GUIDANCE` are the bug and user-setup channels (all in\n  `support\u002Fmacros.h`). Never write to the outputs of\n  `support\u002Flogging` directly, never print\n  diagnostics to stdout\u002Fstderr.\n\n## Naming Conventions\n\n- **Variables, member fields, function names**: `snake_case`. Class member fields do NOT use any special suffix\u002Fprefix (no trailing `_`, no `m_` prefix).\n- **Class names, template parameter names, enum names**: `PascalCase`. Exception: some class names also use `snake_case` — follow the existing style in the project.\n- **Enum values**: `PascalCase`.\n- **Acronyms stay uppercase in type names**: `PCHState`, `LSPClient`, `TUIndex` — never `PchState`, `LspClient`.\n- **A file-local type is named by its role in the file**, without the\n  words of the file's own subject: in an anonymous namespace,\n  `FoldingRangeCollector` in `folding_ranges.cpp` is `Builder`, `ScanOptions`\n  in `scan.cc` is `Options`. A type that is the file's subject itself keeps\n  its name (`Lexer` in `lexer.cpp`).\n- **Nothing is a `Collector`**: the type producing the file's answer is a\n  `Builder`; a visitor gathering nodes is a `\u003CWhat>Finder`\n  (`PackForwardFinder`), or is named by what it gathers (`SpelledNames`); a\n  clang callback that only records what clang reports is a `\u003CWhat>Recorder`\n  (`CompilationUnit::DiagnosticRecorder`).\n- **Overloads, not prefixes, tell one job's variants apart**: every\n  conversion to the LSP form is a `to_protocol` overload (a second form of\n  the same input is named by the form: `to_symbol_information`), and a feature's\n  answer from the index is an overload of its answer from the AST\n  (`semantic_tokens(SourceText&, …)` beside `semantic_tokens(CompilationUnit&,\n…)`) — never `semantic_tokens_to_protocol` or `index_semantic_tokens`.\n- Doc comments on declarations use `\u002F\u002F\u002F`; the bar for when to write a\n  comment at all is in CLAUDE.md.\n\n## Words to Use and Avoid\n\nIdentifiers and comments use plain words: the word a newcomer would guess\nfor the thing, not a metaphor or a rare word that needs a glossary\n(verdict, envelope, ledger). One word means one thing across the codebase —\nbefore naming, grep whether the word already means something else nearby,\nand don't split one concept over two words. A name that its own doc comment\nhas to correct is the wrong name.\n\nThese were renamed out of the codebase; don't bring them back:\n\n| Avoid                                                                                               | Say instead                                                                                                                                                                                                                                                         |\n| --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| row \u002F rows                                                                                          | an index record: `occurrence` \u002F `relation`, else `entry`; a file's whole index data: `index` \u002F `shard` \u002F `variant`; a source line: `line`                                                                                                                           |\n| verdict                                                                                             | `result` \u002F `decision`, whichever the site is                                                                                                                                                                                                                        |\n| claim                                                                                               | one word per site: `take`, `acquire`, `reserve`, `cover`, `report`                                                                                                                                                                                                  |\n| envelope                                                                                            | what it is: `TUIndexBlob`, the TU index, a container, a header                                                                                                                                                                                                      |\n| ledger                                                                                              | `table` \u002F `list`                                                                                                                                                                                                                                                    |\n| wire (the serialized form)                                                                          | `serialized` \u002F `encoded`; \"in the protocol\" for IPC                                                                                                                                                                                                                 |\n| settle                                                                                              | `finish` \u002F `become idle`                                                                                                                                                                                                                                            |\n| flavor                                                                                              | `kind` \u002F `variant`                                                                                                                                                                                                                                                  |\n| land \u002F landing (a result arriving)                                                                  | `commit` \u002F `merge` \u002F `finish`                                                                                                                                                                                                                                       |\n| sweep                                                                                               | `pass` \u002F `run` \u002F `scan`; for cleanup, `remove`                                                                                                                                                                                                                      |\n| tier (an encoding choice)                                                                           | `encoding` (`MaskEncoding`); the search ranking's `NameRank::tier` stays                                                                                                                                                                                            |\n| surface (verb), vouch for                                                                           | `report` \u002F `show`, `guarantee` \u002F `confirm`                                                                                                                                                                                                                          |\n| stamp outside `vfs`                                                                                 | `version` \u002F `generation`                                                                                                                                                                                                                                            |\n| collector                                                                                           | `Builder` \u002F `\u003CWhat>Finder` \u002F `\u003CWhat>Recorder` (see Naming Conventions)                                                                                                                                                                                              |\n| `Features`, `Requests` (the server's request entry points)                                          | the request's handler in `LSPClient` (`server\u002Fclient`), routed by its served project (`ServedProject::pick_route`); the features are `src\u002Ffeature`'s                                                                                                                |\n| projection                                                                                          | what it is: a document's latest compile (`DocumentCompile`), a result computed from the index (the `SourceText` overloads of `semantic_tokens`), the LSP form; only the indexer's step from the semantic map to entries is a projection (`project_node`)            |\n| `switch_source_header` (the feature)                                                                | `counterparts`: the files a file pairs with; only the editor command keeps the action's name (`clice.switchSourceHeader`)                                                                                                                                           |\n| quarantine, barred                                                                                  | the document's crash records (`Session`'s, one `FailureRecord` per request kind); a record `stops` its operation                                                                                                                                                    |\n| strikes                                                                                             | the failure count (`FailureRecord::count`)                                                                                                                                                                                                                          |\n| license (to retry)                                                                                  | the retry a change or a save allows; the `Attempt` holding it                                                                                                                                                                                                       |\n| overtaken (an attempt)                                                                              | `crashed_meanwhile`; a task-graph attempt overtaken by new content keeps the word                                                                                                                                                                                   |\n| parked (crash records)                                                                              | nothing: the records live in the document's `Session` and end with it; a reply a test hook holds, or a waiter on an event, is still parked                                                                                                                          |\n| `BlameBudget`, blaming a PCH pair                                                                   | a failure of its consumption (`pch_consume_failed`), a record with a cooldown policy                                                                                                                                                                                |\n| evidence (kind)                                                                                     | `feature::RequestKind`                                                                                                                                                                                                                                              |\n| ticket (outside a request)                                                                          | a sequence number (`ReindexQueue`'s `seq`); `Ticket` is a request's hold on its buffer                                                                                                                                                                              |\n| superseded (a blob)                                                                                 | `previous`                                                                                                                                                                                                                                                          |\n| `PCHFamily`, `PCMFamily`, `PCHBuilder`, `PCMBuilder`, builder (of PCHs, modules)                    | the PCH and PCM work (`Project::pch_work`, `Project::module_work`) in `project\u002Fgraph\u002Fpch`, `project\u002Fgraph\u002Fpcm`; what both share is `project\u002Fgraph\u002Fprecompiled`                                                                                                      |\n| `TURunFamily`, TU run, unit run                                                                     | a unit's compile (`Project::compile_unit`, `UnitRequest`, `UnitResult`, `NodeKind::Unit`)                                                                                                                                                                           |\n| round (of a graph node, of the background index), `RoundContext`, `RoundOutcome`                    | a graph node's attempt (`Attempt`, `AttemptState`, `Result`); the background index's sweep over its queue is a pass (`BackgroundIndex::run_pass`); round-trip and rounding keep the word                                                                            |\n| outcome                                                                                             | `result`, or the more exact word (`CompileStatus`, `CompilationUnit::status`); kotatsu's `outcome` types keep their name                                                                                                                                            |\n| lend, lent, lender, lending (a command)                                                             | the borrowing side's words: the unit a command is borrowed from (`Candidate::from`, `borrowed_command`), the unit whose command a file borrows; a host's command a header compiles under is the host's                                                              |\n| `Inferred` (a command source)                                                                       | `CommandSource::Borrowed`                                                                                                                                                                                                                                           |\n| `IndexPump`, pump, engine (of the index)                                                            | the background index (`BackgroundIndex`, `BackgroundIndex::run_pass`)                                                                                                                                                                                               |\n| `SchedulingStack`, scheduling stack                                                                 | the project: it builds with the event loop and worker pool its owner gives it (`Project::loop`, `Project::pool`)                                                                                                                                                    |\n| `CommandResolver`                                                                                   | command resolution, members of `Project` (`project\u002Fcommand\u002Fresolve`: `resolve_command`, `command_identity`)                                                                                                                                                         |\n| `PendingTable`, pending table                                                                       | `ReindexQueue`: the background index's queue with each unit's reason                                                                                                                                                                                                |\n| `TakenDebt`, debt (a reindex owed)                                                                  | `TakenReindex`, a reindex                                                                                                                                                                                                                                           |\n| `CommandSnapshot`, command snapshot, `BuildSnapshot`, `SavedListings`, listings                     | `SavedMembers` (blob kind `Members`): which databases listed each file, and the provisional members; a unit's command is its index's `indexed_command`                                                                                                              |\n| `ServingSide`, serving side (the project asking the server)                                         | nothing: the project calls no server; it emits signals (`BackgroundIndex::on_attempt_finished`, `Project::on_index_changed`, `Project::on_metadata_changed`) and its owner hands it the open documents as data (`OpenFile`)                                         |\n| `LiveSources`, `OpenDocuments`, `PeerQueries`, peers (other projects' queries)                      | `IndexQuery`: the open documents its owner hands it (`OpenBuffer`, `IndexQuery::reading`), the other projects it asks (`IndexQuery::asking`, `asked`, `gather`)                                                                                                     |\n| `indexer\u002F` (the background index's directory)                                                       | `project\u002Fbackground\u002F`; `index\u002Findexing` is the indexer that builds a TU's index                                                                                                                                                                                     |\n| `IncludeEdge` (the index's), `include_edges`; `IncludeTree` (analysis')                             | `ResolvedInclude`, `resolved_includes`; `ScopedIncludeTree`; `syntax::IncludeEdge` and `index::IncludeTree` keep theirs                                                                                                                                             |\n| family (of graph nodes)                                                                             | kind (`NodeKind`)                                                                                                                                                                                                                                                   |\n| artifact (a PCH or PCM)                                                                             | precompiled (`Precompiled`, the PCH and PCM records; the blob key `artifacts` stays: persisted)                                                                                                                                                                     |\n| superseded (a unit's index), `mark_behind`                                                          | outdated, `mark_outdated`                                                                                                                                                                                                                                           |\n| sentinel (the graph's node for an import no module provides)                                        | unresolved import (`unresolved_import`)                                                                                                                                                                                                                             |\n| retire, retirement (a unit leaving the build)                                                       | dropped: the build stopped compiling it (`Project::update_members`)                                                                                                                                                                                                 |\n| enterings                                                                                           | `include_chains`: every place a unit's compile enters a header, by its include tree                                                                                                                                                                                 |\n| probe (a header compiled alone, a `__has_include` lookup)                                           | the self-containment check; a `__has_include` `check`                                                                                                                                                                                                               |\n| header mode, `HeaderMode`                                                                           | the self-containment check's result (`SelfContainment`, `Hosting::self_containment`)                                                                                                                                                                                |\n| trial (a header compiled alone)                                                                     | the self-containment check (`SelfContainment`); the precompiled records' `trials` key keeps its spelling                                                                                                                                                            |\n| `HostTree`                                                                                          | `PreprocessedTree` (`Hosting::trees`)                                                                                                                                                                                                                               |\n| lexical chain (the chain a header's context is cut along)                                           | nothing: a chain comes from the host's include tree; the lexical scan only finds the candidate hosts                                                                                                                                                                |\n| standalone header (indexed on its own)                                                              | nothing: only the project's units are indexed, a header through the units reading it                                                                                                                                                                                |\n| workspace (one project or its root)                                                                 | `project`, `project root` (`Settings::project_root`); \"workspace\" is only what the editor opens, its folders; the `--workspace` flag and `${workspace}` in clice.toml keep their spelling                                                                           |\n| `IndexReader`, `ProjectReader`, bootstrap, loading a project                                        | `Project::open` with its `OpenOptions`; a `Project` owns the read side of its index (`index_query`, `freshness`), and a command-line run reads through the `OpenedProject` the driver opens                                                                         |\n| heir, retire (a project), weigh (the databases)                                                     | `successor`, `stop`, `reload_databases`                                                                                                                                                                                                                             |\n| `Selection`, pin, pinned (a context)                                                                | `ContextChoice`, \"choice\" in prose; a choice that stops holding stays `inactive` (`MasterServer::ChoiceEntry`)                                                                                                                                                      |\n| `ProjectServer`                                                                                     | `ServedProject`                                                                                                                                                                                                                                                     |\n| `ASTFamily`, `Dispatcher`, `Invalidator`, `FileTracker`, `EditorContext`                            | what the served project does, in its files: compiling the open documents (`compile.cpp`), what their diagnostics show (`diagnostics.cpp`), answering and asking the workers (`answer.cpp`), handling changes (`changes.cpp`), their commands (`served_project.cpp`) |\n| `Config`, config (what clice.toml holds)                                                            | `Settings` (`load_settings`, `project.settings`); \"configuration\" is only the build configuration a rule's tag names (debug, release), and \"configuration file\" the clice.toml that holds the settings                                                              |\n| epoch (a document's compile), `mark_not_current`                                                    | the AST node's generation (`TaskGraph::generation`): a compile is current while the one it ran at (`DocumentCompile::generation`) is the node's (`ServedProject::current`)                                                                                          |\n| a worker's own LRU, `max_documents`, `document_unloaded`, `EvictedParams`; the pool's `owner` table | the pool's residency (`Residency`: a document's assignment, its AST resident or not, `WorkerPool::resident`, `max_resident`); a worker evicts only when told (`EvictParams`)                                                                                        |\n| hand over (an index)                                                                                | `send_index`                                                                                                                                                                                                                                                        |\n| `ServingMode` (`IndexOnly`, `Escalated`), escalate, escalation, investment (in an open document)    | whether the document is compiled (`ServedDocument::compiles`), from now on (`ServedProject::start_compiling`); otherwise only the index answers it                                                                                                                  |\n| `full_lex`, `await_cold_attempt` (what a request asks of routing)                                   | `RouteOptions::lexes_whole_buffer`, `waits_for_index`; `needs_ast`                                                                                                                                                                                                  |\n| `MasterServer::route`, `reroute`, routing a file to a project                                       | the project a file belongs to: `MasterServer::pick_owner`, `update_owners`; a route is only what answers a request (`pick_route`, `Route`)                                                                                                                          |\n| `uri_to_path`                                                                                       | `feature::to_path`, beside `feature::to_uri`                                                                                                                                                                                                                        |\n| retire, retiring (a worker slot)                                                                    | a scale-down (`scheduler::ScaleDown`, `WorkerPool::scale_down_worker`, `scaling_down`, `SlotState::ScaledDown`)                                                                                                                                                     |\n| `Dead` (a worker slot)                                                                              | `GivenUp`: its crash budget ran out, and only its revival brings it back                                                                                                                                                                                            |\n| `foreground_pulse`                                                                                  | `WorkerPool::user_activity`, as the scheduler's                                                                                                                                                                                                                     |\n| `BuildProbe`, probe (test instrumentation)                                                          | the test hooks: `TestHooks` (`worker\u002Ftest_hooks`), the server's test-only requests in `server\u002Ftest_hooks.cppm`                                                                                                                                                      |\n| culprit, blame (a worker death)                                                                     | the requests a death names (`WorkerDeath::named`); a request charged with a death                                                                                                                                                                                   |\n| preempted (a worker the pool killed)                                                                | `killed_on_purpose`; preempt is the scheduler asking a request to stop                                                                                                                                                                                              |\n| `WorkerCrashInfo`, `on_crash` (the pool's callback)                                                 | nothing: tests read the slot, the user is told by guidance when every worker of a kind is given up; kotatsu's `sys::on_crash` keeps its name                                                                                                                        |\n| `ScopedTimer`, `ms_f`                                                                               | `Timer`, `Timer::precise_ms`                                                                                                                                                                                                                                        |\n| `print_argv`, `host_quoting`                                                                        | `join_command`; `sys::cmd::native_quoting`                                                                                                                                                                                                                          |\n\nDomain words with one meaning each — use them only in that meaning:\n\n- **spelling**: how a path is written — the anchored absolute path,\n  `..` kept, handed only to the identity functions or to clang.\n- **host**: the source file whose compile context a header borrows.\n- **slot**: one worker's place in the worker pool.\n- **stamp**: in `vfs` only, a file's change fingerprint (size + mtime +\n  ctime).\n\n## Templates, Type Traits & Concepts\n\n- `std::remove_cvref_t\u003CT>` only where `T` can be deduced as a reference:\n  a forwarding reference `T&&`. `T`, `T&` and `const T&` parameters,\n  class template parameters and return types never deduce one.\n- A type trait is a variable template specialized directly\n  (`template\u003C> inline constexpr bool is_my_type_v\u003CMyType> = true;`), never\n  a variable template wrapping a class template's `::value`.\n- A concept over a trait uses `T` as is (`concept MyTrait = is_my_type_v\u003CT>;`)\n  unless it deliberately sees through references and cv-qualifiers; the\n  caller passes the right type.\n\n## String Literals\n\n- Prefer C++11 raw string literals `R\"(...)\"` over escaped strings. Avoid `\\\"`, `\\\\`, `\\n` in string literals when a raw literal is cleaner.\n\n## Style\n\n- Definitions stand one blank line apart, which clang-format leaves to the\n  writer, so that a `KANNOTATE_TYPE` sits directly above the type it\n  annotates, the type's doc comment above both.\n- Prefer `[[maybe_unused]]` over `(void)` for intentionally unused variables or parameters.\n- Arithmetic counters step with `x += 1` \u002F `x -= 1`, in `for` heads too — never `++`\u002F`--`; split fused forms like `if(++x > n)` into two statements. Iterators and other types without `+=` are exempt. This applies to code you write or touch, not as a repository-wide sweep.\n\n## Modern C++ Usage\n\n- Use C++20\u002F23 APIs whenever possible. Do NOT use `\u003Ciostream>` facilities (`std::cout`, `std::cin`, `std::cerr`, etc.). Also do NOT use C-style I\u002FO (`printf`, `fprintf`, etc.).\n- Prefer `ranges` \u002F `views` APIs over raw loops and traditional `\u003Calgorithm>` calls.\n- Range helpers come from the standard library, never LLVM's `STLExtras`: `ranges::contains` not `llvm::is_contained` (a set or map uses its own `.contains()`), `ranges::any_of` \u002F `find_if` \u002F `sort` not `llvm::`'s, `views::enumerate` \u002F `zip` \u002F `reverse` \u002F `transform` not `llvm::enumerate` \u002F `zip` \u002F `reverse` \u002F `map_range`. Only `llvm::concat` (C++26 in the standard) and `llvm::interleave` stay.\n- Prefer LLVM's efficient data structures (e.g., `llvm::SmallVector`, `llvm::DenseMap`, `llvm::StringMap`, `llvm::StringRef`) over their `std` counterparts when appropriate.\n- The operating system is reached through kotatsu: paths, files and directories through `fs` (`kotatsu::fs`), the environment, programs and processes through `sys` (`kotatsu::sys`), never `llvm::sys` or `std::filesystem`. LLVM stays where an interface takes its types — `llvm::vfs` for clang's file manager, a `llvm::MemoryBuffer` clang or the index adopts, filled from an `fs::File`. Crashes are `sys::on_crash`'s and the trace `sys::write_stacktrace`'s, never LLVM's signal handling: clang's outputs are not registered for removal on a crash, which would install LLVM's handlers over them.\n- Where a token is, which file holds it and what comes before it are the compile's questions: code holding a `CompilationUnit` asks it (`written_at` \u002F `seen_at` \u002F `produced_at`, the ranges, `before`, `expansion_level`, the tokens), never clang's `SourceManager`, whose answers miss what the unit maps (the PCH's copy of the focus file, the NUL at a completion's point). Each member's doc comment is its contract and a unit test holds it to it; a question the unit lacks is added there, with both. Helpers handed only a `Decl` or an `ASTContext` keep clang's.\n\n## Parameter Passing Preferences\n\n- For string parameters, prefer `llvm::StringRef` > `std::string_view` > `const std::string&`.\n- For array\u002Fspan parameters, prefer `llvm::ArrayRef` > `std::span` > `const std::vector&`.\n",{"name":5,"description":7},"main","a7c62711063ba1ec7e0a1ef65562e194bc6badc4",".claude\u002Fskills\u002Fcpp-style",89,"https:\u002F\u002Fgithub.com\u002Fclice-io\u002Fclice","https:\u002F\u002Fdocs.clice.io\u002Fclice\u002F","https:\u002F\u002Fgithub.com\u002Fclice-io","https:\u002F\u002Fclice.io\u002F","2026-11-13 11:26:47",{"source":8,"skillName":5,"commands":53,"prompt":63,"zipAvailable":64},[54,57,60],{"tool":55,"command":56},"npx","npx skills add clice-io\u002Fclice --skill cpp-style",{"tool":58,"command":59},"bunx","bunx skills add clice-io\u002Fclice --skill cpp-style",{"tool":61,"command":62},"pnpm","pnpm dlx skills add clice-io\u002Fclice --skill cpp-style","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fclice-io\u002Fclice\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcpp-style\u002FSKILL.md",true,[],[67,94,114,135,154,176],{"skillNo":68,"name":69,"nameZh":6,"description":70,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":71,"categories":72,"keywords":83,"publishedAt":38},"01M6BZFHCK196E4Z66DGN9QDYJ","write-tests","Read before writing or modifying anything under tests\u002F or unittests\u002F, or the tools' own tests — the case workflow, unit tests, hard rules and known pitfalls.","https:\u002F\u002Fgithub.com\u002Fclice-io\u002Fclice\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fwrite-tests\u002FSKILL.md",[73,78],{"categoryNo":74,"categoryName":75,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[84,85,86,87,25,88,89,90,91,92,93,35],"write tests","tests","write","pitfalls","case","unit","unit tests","Tools","workflow","Rules",{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":38},"01M6BZFEQ2NCYCKQX0RTMQM55A","upgrade-llvm","Read before upgrading xclang\u002FLLVM (arg = the xclang version, e.g. 23.1.2.1), touching MODULE.bazel, .bazelrc, BUILD.bazel or bazel\u002F, or regenerating modules\u002F — after a library bump, or when clice needs a header or macro it does not export.","https:\u002F\u002Fgithub.com\u002Fclice-io\u002Fclice\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fupgrade-llvm\u002FSKILL.md",[],[101,102,103,104,105,106,25,107,108,109,110,111,22,112,113],"upgrade llvm","llvm","upgrade","export","it","library","build","version","when","module","bump","bazel","macro",{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":120,"publishedAt":38},"01M6BZFCM31QYASHF2XF6G105C","triage","Use when asked to triage issues — classifies untriaged issues with codex, validates the labels, and returns proposed labels plus an activity digest. Read-only; runs in a forked context.","https:\u002F\u002Fgithub.com\u002Fclice-io\u002Fclice\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftriage\u002FSKILL.md",[],[116,121,122,123,124,25,125,126,127,109,128,129,130,131,132,133,134],"fork","context","activity","triage issues","digest","returns","with","use","codex","only","labels","read-only","issues","activity digest",{"skillNo":136,"name":137,"nameZh":6,"description":138,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":141,"publishedAt":38},"01M6BZFAW6TTR0FK91HZ0TVNFS","translate-docs","Read before translating, reviewing or editing any docs\u002Fzh page — clice's glossary and page conventions, on top of the shared translation rules of clice-io\u002Fdocs.","https:\u002F\u002Fgithub.com\u002Fclice-io\u002Fclice\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftranslate-docs\u002FSKILL.md",[],[142,143,144,145,146,147,25,148,149,150,151,152,93,153],"docs","translate","translate docs","conventions","io","zh","top","translation","shared","editing","page","glossary",{"skillNo":155,"name":156,"nameZh":6,"description":157,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":158,"categories":159,"keywords":163,"publishedAt":38},"01M6BZF86F54V9BZCW3MJW82VY","test","Run the clice test suites, on a box unless a local run is truly necessary; also how to test on Windows. Optional args = suite (unit | cases | all, default all) build type (Debug | RelWithDebInfo, default RelWithDebInfo) and the box id the build ran on. Runs in a forked context; only a digest returns.","https:\u002F\u002Fgithub.com\u002Fclice-io\u002Fclice\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftest\u002FSKILL.md",[160],{"categoryNo":161,"categoryName":162,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000008","测试与质量",[156,164,89,126,165,166,167,168,169,170,171,122,172,125,107,121,173,174,130,175],"default","run","how","debug","box","windows","local","local run","suite","id","type","how to",{"skillNo":177,"name":178,"nameZh":6,"description":179,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":180,"categories":181,"keywords":182,"publishedAt":38},"01M6BZF5WRJ6PKYJVW4YKPYD20","resolve-comments","Use in each watch round of an open PR — pulls its unresolved review threads, fixes them in the worktree, resolves them, and returns a compact summary.","https:\u002F\u002Fgithub.com\u002Fclice-io\u002Fclice\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fresolve-comments\u002FSKILL.md",[],[183,184,128,185,186,187,188,189,126,190,191,192,193,194],"comments","resolve comments","watch","compact","summary","fixes","threads","review","open pr","worktree","pr","open"]