Skip to content

Diagnostics & rules reference

English(this file) · 日本語

karasu reports problems with two layers of vocabulary:

  • A rule (規則) is a concept — what the language allows and forbids (“an edge originates within its enclosing block”). Rules are how authors and this spec talk about the constraint.
  • A diagnostic (診断) is a mechanism — a specific, named check that fires when one concrete violation of a rule is detected (edge-source-mismatch).

One rule is often enforced by several diagnostics, and a single diagnostic belongs to exactly one rule. This document is the catalog that maps the two.

  • Diagnostic codes are stable API. The code string (e.g. edge-source-mismatch) is consumed by the LSP, the app, and downstream tooling. Codes are not renamed to match a rule’s wording; the rule name is conceptual, the code is the contract. When a rule reads more naturally under a different name than its diagnostic, that is expected — they sit at different altitudes.
  • Every diagnostic code lives under exactly one rule family below, and every code defined in core (DiagnosticParamsByCode, WarningKind) appears here. This completeness is enforced by a meta-test (see Catalog completeness), so a new code cannot ship without a catalog entry.
  • The fires when column states the concrete trigger. Severities are listed as emitted by core.

A diagnostic has a severity: error, warning, or info.

  • error — the model is malformed; the offending construct is rejected.
  • warning — a real defect the author should fix (a dangling reference, a conflicting style).
  • info — a fact, not a defect. karasu surfaces something true about the model that an external school of thought may call a smell (a shared database, a dispersed domain), without asserting it is wrong. This is the fact vs. style register split — see TPL-20260514-08.

karasu also follows warn-don’t-error for unresolved references (spec §S6): an unresolved relation is dropped while the node it points from is preserved, and the drop is reported as a warning rather than failing the whole render.

Where a construct may be declared, and what an edge’s origin may be. An edge declared inside a service / domain block originates from that block’s id; infra blocks and legend have fixed placement; sync edges must not form a cycle.

CodeSeverityFires when
edge-source-mismatcherrorAn explicit edge source inside a service / domain block does not equal the enclosing block id (the edge origin scope rule).
ambiguous-edge-basewarningMultiple edges share the same from → to base with no distinguishing author id.
service-outside-systemwarningA service is declared outside any system.
infra-not-in-contexterrorAn infra block (database / queue / storage) is not a direct child of system.
legend-not-top-levelerrorA legend block is declared somewhere other than the top level.
top-level-declarationerrorA user or an edge is declared at the top level instead of inside a system block.
system-property-conflictwarningA system label / description conflicts between merged imports.
cyclic-dependencywarningSync edges (->) form a dependency cycle.

Ids must be unique within their declaring scope; ownership assigns at most one primary owner.

CodeSeverityFires when
duplicate-edge-iderrorAn author-supplied edge id collides with another edge’s id.
duplicate-node-id-parenterrorA node id is duplicated within its immediate parent.
duplicate-node-in-systemerrorA node id is duplicated within a system.
duplicate-node-in-deployerrorA node id is duplicated within a deploy block.
duplicate-team-iderrorA team id is duplicated.
duplicate-team-in-organizationerrorA team id is duplicated within an organization.
duplicate-resource-operationwarningA CRUD verb is listed more than once on one resource.
duplicate-crud-decoration-targetwarningA CRUD decoration targets the same operation more than once.
duplicate-owner-assignmentinfoA node is assigned as owned by more than one team (a fact; see ADR-20260615-01).
node-id-multiple-locationswarningThe same node id appears in more than one location.

Cross-reference resolution (warn-don’t-error, §S6)

Section titled “Cross-reference resolution (warn-don’t-error, §S6)”

A referenced id must resolve to a declared node. When it does not, the source node is preserved and the unresolved relation is reported (it is not a fatal error) — see syntax spec §S6.

CodeSeverityFires when
owns-target-not-foundwarningA team owns a service / domain that does not exist.
invalid-ownswarningAn owns target resolves to a kind that cannot be owned.
import-id-not-founderrorA named import id path fails to resolve.
import-path-not-founderrorAn import path fails to resolve at some segment.
unresolved-edge-endpointwarningAn edge endpoint id is not found anywhere in the merged model.
unresolved-handleswarningA handles domain is not reachable through the one-hop expose rule.
unresolved-realizeswarningA deploy node realizes a target absent from the logical layer.
legend-ref-unresolvedwarningA legend ref matches no style rule and no node.
cross-system-ref-unresolvedwarningA cross-system edge (Sys.Svc) target is not found.
cross-system-ref-implicit-externalwarningA cross-system edge crosses into a system not tagged [external].
delivers-target-not-clientwarningA delivers target is not a client node.

Infra nodes are declared once; a store referenced by several services is a fact worth surfacing.

CodeSeverityFires when
infra-redeclared-across-filesinfoThe same database / queue / storage id is declared in more than one merged file.
infra-leaf-redeclared-silentlyinfoA table / queue-item / bucket leaf is redeclared within its parent infra.
shared-infra-fan-ininfoTwo or more services depend on the same store within one system (a fact, not a defect).

The grammar of operation / CRUD decoration on resources.

CodeSeverityFires when
invalid-crud-decorationerrorA CRUD decoration uses an unrecognised verb / letter.
empty-crud-decorationwarningA verb: decoration has an empty right-hand side.
unknown-resource-operationwarningA resource operation verb is not one of create / read / update / delete.

Whether structural nodes are assigned to an owner / parent, and cohesion facts about how domains and deploy targets are wired.

CodeSeverityFires when
unassigned-servicewarningA service sits at top level with no team assignment.
unassigned-domainwarningA domain sits at top level with no team assignment.
unassigned-usecasewarningA usecase is a direct child of a service with no domain parent.
unassigned-clientwarningA client sits at top level with no team assignment.
unassigned-databasewarningA database sits at top level with no team assignment.
unassigned-queuewarningA queue sits at top level with no team assignment.
unassigned-storagewarningA storage sits at top level with no team assignment.
unassigned-resourcewarningA resource is declared inline without a dot-notation assignment.
domain-dispersalinfoOne domain id appears under multiple services in scope (a fact).
missing-realizesinfoA deploy node lacks a realizes property.
missing-runtimeinfoA deploy node lacks a runtime property.

Annotation parameters and removed / deprecated properties.

CodeSeverityFires when
annotation-param-unsupportedwarningAn annotation parameter key is not recognised for that annotation.
annotation-possible-typoinfoAn annotation name is a near-match to a builtin (typo hint).
team-property-removederrorThe removed team property is used (see ADR-20260614-01).

Resolving import declarations and style imports against the filesystem.

CodeSeverityFires when
circular-importwarningA node import forms a cycle.
circular-style-importwarningA style import forms a cycle.
file-not-founderrorAn imported file does not exist.
directory-not-founderrorAn imported directory does not exist.
style-file-not-foundwarningAn imported style file does not exist.

Validating .krs.style property names and values.

CodeSeverityFires when
style-unknown-propertywarningA style property name is not recognised.
style-invalid-enum-valueerrorA style value is not in the allowed enum.
style-invalid-hex-colorerrorA style hex color is malformed.
style-invalid-length-uniterrorA style length uses a disallowed unit.
style-missing-length-uniterrorA style length is missing its required unit.
style-out-of-rangeerrorA style numeric value is outside its min / max bounds.
style-token-type-mismatcherrorA style token does not match the expected type.
expected-style-property-nameerrorThe style parser expected a property name.
expected-semicolon-between-propertieserrorThe style parser expected a ; between properties.
unknown-edge-selector-attributeerrorAn edge selector uses an attribute other than from / to (e.g. edge[source=X]).
style-conflictwarningA selector is defined in more than one user style sheet.
style-column-invalid-valuewarningA style column value is not left / center / right.
style-column-ignored-non-system-viewwarningA column hint is applied to a deploy / org view (ignored).
style-grid-columns-invalid-valuewarningA style grid-columns value is not a positive integer (the hint is dropped; layout auto-balances).

The client sub-language: storage kinds and capabilities.

CodeSeverityFires when
client-resource-invalid-kinderrorA client resource storage kind is not one of the reserved values.
client-capability-duplicatewarningA client declares the same capability name twice.

Low-level parser errors raised when tokens do not form a valid construct. These are mechanism-level by nature; the “rule” is the grammar itself.

CodeSeverityFires when
token-type-mismatcherrorA token does not match the type the parser expected.
unexpected-token-rooterrorAn unexpected token appears at the root level.
unexpected-token-in-blockerrorAn unexpected token appears inside a block.
expected-brace-or-stringerrorThe parser expected a { or a string literal.
expected-identifiererrorThe parser expected an identifier.
expected-string-aftererrorThe parser expected a string after a property keyword.
expected-id-or-stringerrorThe parser expected an id or a string.
expected-node-iderrorThe parser expected a node id.
expected-property-valueerrorThe parser expected a property value.
expected-id-aftererrorThe parser expected an id after a property keyword.
invalid-node-kinderrorA node kind keyword is not recognised.
property-not-for-node-kinderrorA property is not valid for the node kind it appears on.
link-url-scheme-not-allowedwarningA link URL scheme is not in the allowed set (http / https / mailto).

Synthetic codes the app uses when wrapping a thrown compile / parse error.

CodeSeverityFires when
app-project-compile-errorerrorcompile() threw and the app reports a generic compile failure.
app-org-parse-errorerrorOrg parsing threw and the app reports a generic parse failure.
generic-texterrorA pre-built fallback message string with no structured params.

Every member of DiagnosticParamsByCode and WarningKind (in packages/core/src/types) must appear as a code in this document. A meta-test (packages/core/src/types/diagnostics-catalog.test.ts) asserts this in both directions, so the catalog cannot silently drift from the emitted codes. The discipline behind it is recorded as TPL-20260616-02.

Related TPLs: TPL-20260616-02 (catalog ↔ code completeness), TPL-20260514-08 (fact vs style register), TPL-20260610-02 (spec-promised diagnostics are implemented), TPL-20260511-02 (spec ↔ source-of-truth sync).

© 2026 Hiroki Kondo · Licensed under Apache-2.0