Source of truth:
- Syntax:
grammar/MusiParser.g4,grammar/MusiLexer.g4,grammar/Musi.abnf - Ownership and crate map:
docs/where/workspace-map.md - Public API inventory:
docs/reference/public-api.md
- No placeholders in
crates/:todo!(),unimplemented!(), placeholder panics, empty pipelines. - Documentation and feature-matrix notes describe current implementation behavior. They do not declare language support policy.
src/is production-only. Unit tests live inmodule/tests.rs. Benches live inbenches/and use Criterion withbench_prefix.- Cargo TOML syntax:
- workspace-inherited package metadata uses
field.workspace = true - dependency entries use
dep = { workspace = true } - never write dependency entries as
.workspace = true
- workspace-inherited package metadata uses
- Prefer longform names:
lexer.rs,parser.rs,syntax,sema. - Reserve
Syntax*for syntax trees, not token streams. - Lexer nouns stay short:
Token,TokenKind,Trivia,Lexer. - Keep trivia types in
trivia.rs. - Prefer top-level
useimports and local names in signatures and implementation code. - Do not write fully qualified paths such as
music_hir::Foo,music_arena::Bar, orcrate::mod::Typeinside function bodies, match arms, or helper signatures just to name ordinary types or variants. - Absolute singleton uses are only acceptable for real singletons such as
crate::CONST,crate::func(), and macros. - Do not introduce new macros in this repo.
Vec<Item>=>ItemListBox<Item>=>ItemPtrorBoxedItemResult<T, XError>=>XResult<T = ()>- If one composite type appears 2+ times in one module public surface, alias it.
- Alias names must describe owned concept, not only container shape. Prefer
CallFrameListover generic names such asFrameListwhen ambiguity exists.
- Do not create God objects, God modules, or catch-all files.
- If one type or file starts owning unrelated responsibilities such as collection, normalization, checking, diagnostics, effect handling, lowering, and declaration validation all at once, split it.
- Prefer small coordinating facades over monolithic structs.
- Organize
music_semaand later phases by responsibility such ascollect,normalize,check,effects,attrs,ffi, not by one giant checker file. - Helpers belong with owning subsystem. Shared helpers should remove real duplication, not become generic sink modules.
- Use
.agents/skills/musi-diagnosticsfor diagnostic wording, labels, renderer, or test work. - Canonical guide:
docs/reference/diagnostics.md. - Every diagnostic must come from typed diagnostic enums in its owning crate or phase. Do not construct freeform user-facing diagnostics ad hoc.
- Diagnostic tests outside diagnostic-focused modules must assert enum kind or code, not full message text.
- Diagnostic wording uses subject-first diagnostic style:
- lead with offending item or condition
- prefer noun-first or adjective-first phrasing such as
unsupported opcode \foo`ormissing export `bar`` - avoid predicate-heavy wording such as
item \x` is not supported`
- Diagnostic headlines must identify exact offending source text, symbol, operator, field, variant, import specifier, type, or expected/found pair when known.
- Diagnostic headlines must not use articles:
a,an,the. - Diagnostic headlines should avoid weak linking verbs where practical:
is,was,but. - Diagnostic headlines must not use chained
message1: message2formatting. - Hints belong on hint/help lines only when they provide real correction guidance. Do not use hints to restate headline text.
- Primary labels should point at offending token, value, name, or span whenever source location exists.
- Prefer concrete, single-sentence messages with exact offending item named in backticks.
- Phase DAG has no cycles:
music_base -> music_names -> music_syntax -> music_module -> music_resolve -> music_sema -> music_irmusic_ir -> music_emit -> music_sessionmusic_ir -> music_jit -> music_sessionis planned
- SEAM transport stays
music_bc -> music_assembly. - Project integration lives above compiler/runtime phases in
musi_projectandmusic_session. - Pre-resolve contracts use
*Envnames, not*Resolver.