docs(safety): document the unsafe contract end-to-end

After Opt #2 added six bounded `get_unchecked` blocks per chart, the
project's two "no unsafe" claims (README §"At a glance" + spec §11
rule 12) were stale, and there was no single place answering "how
do I know the unsafe is correct?".

This commit closes both gaps:

- New: docs/004. unsafe-safety-contract.md
  Inventories every unsafe site, names the predicate, names what
  establishes it (codegen-time guarantee), and lists the five
  layered checks (const-eval, debug_assert, miri, mutants, Creusot)
  with current status. Documents what's *not* yet covered (the
  16-of-53 missed mutants in the LCA depth walk are behavior, not
  safety; transition() codegen invariants are still Phase-4 for
  Creusot). Includes a maintenance checklist for future unsafe.

- README points at the doc and gives an honest one-paragraph
  summary instead of "no unsafe".

- Spec rule 12 rewritten from "no unsafe in generated code" to
  "bounded unsafe in generated code, none in user code" with a
  pointer to the audit.

- justfile gains `just safety` — runs const-eval (cargo check),
  debug_assert tests, miri, and mutants in one shot. Mirrors the
  doc's audit matrix so the doc never goes stale silently.
This commit is contained in:
swaits committed 2026-05-04 15:29:24 -06:00
1 parent 98352b0e4d
commit ad2aa6e04d
4 files changed
+224 -4

No files matched your search

+8 -1
View File
@@ -1186,7 +1186,14 @@ The crate is considered complete when:
11. **Timer precision.** Timers fire on the first `step()` call where cumulative elapsed time meets or exceeds the duration. They do not fire early.
12. **No unsafe code** in the public API or generated code (implementation may use unsafe internally if justified and documented).
12. **Bounded `unsafe` in generated code, none in user code.** The
generated dispatch path uses six `slice::get_unchecked` blocks
for hot-path table indexing; their bounds are guaranteed at
codegen time, checked at build time by const-eval, in dev/test
by `debug_assert!`, and in CI under Miri. Inventory + audit in
[`docs/004. unsafe-safety-contract.md`](./004.%20unsafe-safety-contract.md).
User-facing code (chart definitions, action bodies, durings,
public API surface) contains no `unsafe`.
13. **Documentation.** Every public type, method, and trait has rustdoc with examples.