Skip to content

Add Claude support: a CLAUDE.md, path-scoped rules and skills #178

Closed

Description

@martin-fleck-at

Feature Description

Add Claude support to the repository: a CLAUDE.md at the root, path-scoped rules under .claude/rules/, and the few skills that hold a procedure — each piece in the place Claude Code loads it from.

There is no CLAUDE.md at the root, and the only skills are .claude/skills/langium, vendored from eclipse-langium/langium-ai in #194, and .claude/skills/writing-docs from #340, which points at the documentation rules. So an agent working in a clone begins with no pointer to the conventions a change is held to, the gate it has to keep green, or which head a change belongs in.

This is guidance for changing the framework, not for building a language on it — the adopter direction is #100. Several pieces name the framework side of a seam that also has an adopter page: the page says how to override the seam, the rule says how the bound default behaves.

Where each piece goes. Claude Code's documentation sorts guidance by shape. A fact every session needs goes in CLAUDE.md; a fact that "only matters for one part of the codebase" goes in a path-scoped rule, which loads when Claude works on matching files; a multi-step procedure goes in a skill. Instructions are advisory, so a mistake a check can catch gets the check instead of prose. Whether a skill helps is measured rather than argued: the same prompts in fresh sessions, with the skill and without it.

The root file. Most of what it would otherwise explain is already written. docs/contributing/design/ holds nine pages stating each seam as a contract, docs/guides/ ten how-to pages, and conventions requires every declaration comment to carry the constraint, what breaks, and the rejected alternative. What the root file owes is pointers into that, the gate, and which head a change belongs in.

A first step. Claude Code's /init writes a starter CLAUDE.md from the repository, and running it shows quickly what the root file adds. Its commands survive the sorting above: the npm version nothing selects, the gate's verdict line, mirroring CI through ci-changed.mts, the single-test commands, and that examples and e2e read built lib. Its architecture overview restates the README, each package's description and CONTRIBUTING's design index. It can't know which head a change belongs in, or the rules. The draft also has to be wrapped to 80 columns and linked from an index, or check:docs fails it.

Rules, one per area. Each is a fact a change in that area gets wrong while the gate stays green:

  • Test files. Instrument with process.stderr.write, not console.*: Vitest prints a test's console output only when that test fails, filed under whichever test is running when the line is written, so a line from a passing test never shows and a late one lands under the wrong test; stderr prints either way. And the *.types.test.ts convention: nine files across core, protocol and data-server assert type-level behaviour with @ts-expect-error under typecheck:test, so a constraint that stops holding reddens that file and nothing else. testing states neither.
  • Scope. HydraniumScopeProvider.getProjectScope returns the global scope unchanged when ProjectManager.isSingleProject(), which the bound SingleProjectManager always reports — so the tier machinery is inert in a default workspace, and a tier-filter test written against a default services bundle cannot fail. Customizing names and scope presents the tiers without that, and gets the fact as well.
  • The GLSP head. A diagram module that extends GLSP's DiagramModule, or a base of its own, instead of AbstractHydraniumGlspDiagramModule compiles and runs without the framework's overrides: without the status bindings nothing tells the client why its diagram is read-only, and without the operation and undo handlers, operation handlers edit the built root every reader shares.
  • The CLI. hydranium-cli is head-neutral: every command works on any language built on the framework and reaches a head only through the module its --services or --server flag names, so an adopter's domain codegen stays out of it. The core function a new harness subcommand drives belongs in @hydranium/core/node, not in the CLI package: the harness resolves that module from the head's dependencies, so the function runs on the same copy of core as the head.

Checks instead of rules. Two of the facts can be enforced, which leaves nothing to write down:

  • A domain error must not define both expected and actual. A reporter that reads such a pair as an assertion failure diffs them and assigns the prettified values back, which throws on getter-only properties and reports nothing about the real assertion. ConflictError's baseVersion getter records this for its own pair; an ast-grep rule under check:ast-grep would hold it for the next error.
  • AstExtensionService.register and BuildPhasePassService.register accept any state, so an extension or a pass registered at a document state the build pipeline never notifies is accepted and never fires. Each register can refuse a state outside the phases the pipeline wires, as IntegrityService.register already does.

Skills. Heap analysis is the one in hand: hydranium-cli analyze-heap ships, and reading its output is a procedure that needs the framework's own retention structure — which concepts co-own an AST, and what a description's node pointer holds alive. Others earn a skill when a procedure recurs and the with-and-without comparison shows it helps.

Whether anything checks the guidance still matches the code. A symbol reference can be checked mechanically, a prose claim about behaviour cannot, and it is the prose that goes wrong. check:docs holds the root CLAUDE.md, our own skills and the path-scoped rules to the same link and rot checks as the pages; the root file is reached through CONTRIBUTING, and skills and rules need no index because the tool finds them. Claude Code's /doctor prompt-audit reports references to files that don't exist and instructions that contradict each other, but runs in a session rather than the gate. The open question is what checks a claim about behaviour, now tracked in #434.

Additional Context

Related to #100, which runs the other way — guidance delivered into an adopter's own project. This one is about working inside this repository, and the two can share content without sharing a delivery mechanism.

Activity

  1. added
    documentationPages under docs/, READMEs and API doc comments
    enhancementA new capability or an improvement to an existing one
    on Sep 21, 2026
  2. changed the title [-]Add Claude support: a `CLAUDE.md` and a skill set[/-] [+]Add Claude support: a CLAUDE.md, path-scoped rules and skills[/+] on Oct 11, 2026
  3. martin-fleck-at commented on Oct 14, 2026

    @martin-fleck-at
    ContributorAuthor

    All parts have landed: the root CLAUDE.md in #421 (and the PR-template pointer in #431), the path-scoped rules in #430, the GLSP-head rule as a check in #427, the two checks in #422 and the heap-analysis skill in #452. The open question, what checks that guidance still matches the code, continues in #434. Closing.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationPages under docs/, READMEs and API doc commentsenhancementA new capability or an improvement to an existing one

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions