code-moniker 0.1.0

Standalone CLI / linter for the code-moniker symbol graph: per-file probe, directory summary, project-wide architecture rules.
Documentation
# code-moniker default rule pack — embedded into the binary at build time.
# Users override per-project via `.code-moniker.toml` at the repo root.
#
# Each `[[<lang>.<kind>.where]]` entry is a single assertion in the form
# `<lhs> <op> <rhs>`. A def violates the rule when the assertion is false.
# Suppress with `// code-moniker: ignore[<lang>.<kind>.<id>]`.
#
# Embedded defaults stick to structural / naming hygiene that is broadly
# uncontroversial. Project-specific policies (comment-content allow-lists,
# doc-comment requirements, max-lines/max-methods budgets) belong in the
# user overlay — see docs/check-dsl.md for a worked example.

# Aliases factor the case regexes shared across languages. A user overlay
# may redefine any of these to tighten or loosen the convention without
# touching the per-kind rules.
[aliases]
pascal    = "name =~ ^[A-Z][A-Za-z0-9]*$"
camel     = "name =~ ^[a-z_][A-Za-z0-9]*$"
snake     = "name =~ ^[a-z_][a-z0-9_]*$"
screaming = "name =~ ^[A-Z][A-Z0-9_]*$"
go_id     = "name =~ ^([A-Z][a-zA-Z0-9_]*|[a-z][a-zA-Z0-9_]*)$"

# ─── TypeScript / JavaScript ──────────────────────────────────────────────
[[ts.class.where]]
id      = "name-pascalcase"
expr    = "$pascal"
message = "Class names must be PascalCase. Rename `{name}`."

[[ts.interface.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[ts.type.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[ts.function.where]]
id      = "name-camelcase"
expr    = "$camel"
message = "Function names use camelCase. Rename `{name}`."

[[ts.function.where]]
id      = "no-placeholder-names"
expr    = "name !~ ^(helper|helpers|utils|util|manager|temp|tmp|handleData|processData|newFunction[0-9]*)$"
message = "`{name}` is a placeholder name. Pick a verb that describes the actual behaviour."

# ─── Rust ─────────────────────────────────────────────────────────────────
[[rust.fn.where]]
id   = "name-snakecase"
expr = "$snake"

[[rust.struct.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[rust.trait.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[rust.type.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[rust.enum.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[rust.const.where]]
id   = "name-screaming"
expr = "$screaming"

# ─── Java ─────────────────────────────────────────────────────────────────
[[java.class.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[java.interface.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[java.method.where]]
id   = "name-camelcase"
expr = "$camel"

[[java.field.where]]
id   = "name-camelcase"
expr = "$camel"

[[java.enum_constant.where]]
id   = "name-screaming"
expr = "$screaming"

# ─── Python ───────────────────────────────────────────────────────────────
[[python.function.where]]
id   = "name-snakecase"
expr = "$snake"

[[python.class.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[python.method.where]]
id   = "name-snakecase"
expr = "$snake"

# ─── Go ───────────────────────────────────────────────────────────────────
[[go.type.where]]
id   = "name-go"
expr = "$go_id"

[[go.const.where]]
id   = "name-go"
expr = "$go_id"

# ─── C# ───────────────────────────────────────────────────────────────────
[[cs.class.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[cs.interface.where]]
id   = "name-i-prefix"
expr = "name =~ ^I[A-Z][A-Za-z0-9]*$"

[[cs.record.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[cs.method.where]]
id   = "name-pascalcase"
expr = "$pascal"

[[cs.property.where]]
id   = "name-pascalcase"
expr = "$pascal"

# ─── SQL / PL/pgSQL ───────────────────────────────────────────────────────
[[sql.function.where]]
id   = "name-snakecase"
expr = "$snake"

[[sql.table.where]]
id   = "name-snakecase"
expr = "$snake"

[[sql.view.where]]
id   = "name-snakecase"
expr = "$snake"

# ─── Cross-language structural invariants ────────────────────────────────
# These use the `shape` projection (see docs/check-dsl.md "Shape — the
# canonical kind grouping") to express rules that hold regardless of
# which language's kinds are involved.

# Annotations have no business calling code or referencing types — they
# are leaf nodes in the graph by construction.
[[refs.where]]
id      = "annotations-do-not-emit-non-annotates-refs"
expr    = "source.shape = 'annotation' => kind = 'annotates'"
message = "An annotation def (`{source.name}`) emitted a `{kind}` ref. The annotation shape is leaf — only `annotates` refs originate from it."