make spec infra more ergonomic

Signed-off-by: Onur Özkan <work@onurozkan.dev>
This commit is contained in:
Onur Özkan committed 2026-07-18 13:28:01 +03:00
1 parent b0a7a9bb03
commit 85559bd2d5
20 files changed
+74 -123

No files matched your search

+16 -10
View File
@@ -1,28 +1,34 @@
# Specifications
Formal Kaptan specifications should normally live next to the code item they govern.
Formal Kaptan specifications live next to the file-backed module they govern.
Examples:
- `kaptan-runtime/src/control_loop.rs`
- `kaptan-runtime/src/control_loop.spec.md`
- `kaptan-runtime/src/runtime.rs`
- `kaptan-runtime/src/runtime.spec.md`
- `kaptan-runtime/src/scheduler.rs`
- `kaptan-runtime/src/scheduler.spec.md`
## Compile-Time Linking
## Automatic Sidecar Checks
Code implementations should link to their governing spec through `#[spec("...")]`.
Kaptan build checks require a same-name `.spec.md` sidecar for every file-backed Rust module under a checked crate's `src/` tree.
Example:
For example, `control_loop.rs` requires `control_loop.spec.md` in the same directory. A checked module must have exactly one of:
- its sidecar specification; or
- a top-level `no_spec!("reason");` declaration.
`no_spec!` is only for module files that intentionally have no formal specification, such as a crate root that only declares child modules. It must provide a non-empty reason and must not be used for types, functions, or individual items.
Example for a crate root without standalone runtime behavior:
```rust
use kaptan_spec::spec;
use kaptan_spec::no_spec;
#[spec("control_loop.spec.md")]
pub struct ControlLoop;
no_spec!("Crate root declares child modules only.");
```
The attribute expands to a compile-time file inclusion guard. If the linked file does not exist, compilation fails.
The build fails if a required sidecar is missing or a module contains both a sidecar and `no_spec!(...)`.
## Spec Format