Skip to content

The CeeSafe Specification ​

CeeSafe is a memory-safe systems programming language with C#/TypeScript-style syntax, compiled ahead of time to portable C. This directory is its specification. ceesafec embeds it: ceesafec explain and the MCP server (ceesafe_spec_search, ceesafe_spec_section, the ceesafe://docs/… resources) serve this text.

1. Documents ​

Normative, in order of authority after the ADRs:

DocumentWhat it specifies
decisions/the ADRs: accepted decisions override the other documents' proposals (§2)
ownership.mdthe safety invariants (O*, B*, E*, R*, H*, U*) and their formal design
language-spec.mdthe language: goals, syntax overview, semantics
grammar.mdthe grammar
type-system.mdtypes and static semantics, the built-in types and libraries, chapter by chapter
lifetimes.mdreferences and the borrow checker
memory-model.mdallocation, regions, placement
unsafe.mdunsafe, raw pointers and their contract
c-backend.mdthe generated C: its rules, names, ABI version, structure
optimisations.mdeach optimisation's preconditions and checks
profiles.mdthe hosted and freestanding profiles and their runtimes
diagnostics.mdevery diagnostic code
tooling.mdthe command line, doc, lsp, debugging, packages, fixes, explain, mcp, agent files
formatting.mdthe canonical style ceesafec fmt writes
api/core.mdlib/core's API, generated by ceesafec doc

Descriptive: architecture.md (how ceesafec is built), intermediate-representation.md (the AST, HIR and NIR as implemented) and testing.md (how CeeSafe is tested).

The guide teaches the language; every example in it is compiled by tools/guide_check.py. Both are published at ceesafe.github.io/CeeSafe (the repository's site/).

2. Decisions ​

CeeSafe began as a port of an earlier compiler. decisions/0001–0030 are that compiler's ADRs, inherited with their text unchanged, under a header that says so. CeeSafe's own language decisions continue the series from ADR 0031 in the same directory. The repository's own decisions (names, bootstrap, releases) are "Decisions" in its docs/decisions/, a separate series.

3. Names ​

The compiler, its files and the C it generates use CeeSafe's names:

  • the compiler is ceesafec; source files are .cee; packages are ceesafe.toml and ceesafe.lock, the cache is $CEESAFE_HOME (default ~/.ceesafe), and the default registry index is github.com/CeeSafe/CeeSafe-index;
  • the command line reads only .cee and .c files (tooling.md);
  • the generated C and the runtime use CeeSafe's names: cee_, ceeF_, ceeMk_, … for generated names, and ceesafe_*, CEE_*, CEESAFE_*, ceesafe/rt.h for the runtime; programs may not declare C names with those prefixes (N0292); and ceesafe/rt.h defines CEESAFE_ABI_VERSION, which every generated unit checks (c-backend.md §1.1);
  • messages say CeeSafe: ceesafe panic: ….

4. Reading this text ​

  • Milestone tags (M1–M15, C0–C9, K1–K7, G7b, …) name the milestone that introduced a rule. They are kept so a rule can be traced to its history; they say nothing about CeeSafe's plan, which is the repository's ROADMAP.md.
  • CosmoOS. The kernel profile, lib/kernel and the CosmoOS bindings were developed inside CosmoOS, which builds its CeeSafe code with the ceesafec it pins.
  • Paths. src/… is ceesafec's source. lib/… and runtime/… name the library and runtime sources ceesafec embeds (architecture.md §6). tests/corpus/…, benchmarks/… and programs/… are under tests/reference/. integrations/cosmoos/… holds the CosmoOS checks (testing.md §1).
  • Tests. Where a rule is checked by a test, the text names its tool (testing.md).

5. Changing it ​

Spec before code: a change to the language changes this specification first, with an ADR when it is a decision, and then the compiler, its tests and the guide.

Pre-1.0: the language and its tools are still changing.