Second tranche of the contracts-against-code audit. Two threads, both applied conservatively under the over-correction guards in docs_honesty_pin.rs (the self-labelled tiebreaker in 0008 and the Diverge-reserved anchor in 0010 are deliberate honest content and were left untouched; design rationale that explains a present-state design principle — semantic-locality, the reuse-as-wrapper reasons — was also preserved). Honesty-rule (0007): demote clear change/deletion narration to present tense. - 0008: drop "they were promoted from ... to ... Recorded here so"; strip the "Iter A"/"Iter B" iteration labels (the descriptive titles carry the meaning); drop "(no longer a carve-out)". - 0001: "were rewired to use ... was deleted at the same time" -> present tense. (The substance was already correct: `pretty.rs` holds only the diagnostic helpers; an audit agent had misread the line as "pretty.rs was deleted" — the file exists, the printer code does not.) - 0012: drop "Per the tail-call survey of existing fixtures" and "Migration of existing fixtures is partial" -> present-state description of which corpus fixtures carry the tail marker. Ratifier integrity: a contract that names a test which does not ratify it is itself a form of the dishonesty this ledger forbids. - 0014 named `bench/architect_sweeps.sh`, which sweeps honesty-anchors and ratifies none of the six verification mechanisms; and claim 5 cited `tests/expected/`, which never existed (git log empty). Point claim 5 at the real golden mechanism (`crates/ail/tests/snapshots/` via `ir_snapshot.rs`) and the footer at each mechanism's actual test. - 0015's four constraints are guaranteed by absence (no thunk/`ref`/ `IORef` node, non-recursive `let`); the named uniqueness in-source tests only count RC consumes, never the constraints. State the by-construction guarantee and point the ratifier at `ast.rs` (the single source of truth for which nodes exist). - INDEX ratifying-test column updated for both to match. All ledger pins green (docs_honesty_pin, design_index_pin incl. every_contract_names_a_resolvable_ratifying_test, effect_doc_honesty_pin, carve_out_inventory); architect honesty sweep clean. Deferred, recommend-only: 0016-method-dispatch carries no invariant absent from 0013 (merge candidate), but a contract-file merge touches INDEX, the retired-counter convention, and cross-refs — a structural call left for explicit direction. Minor history phrasing in 0008's Type::Con.name hash-shift paragraph (§"FnDef.suppress") also left.
2.2 KiB
Language-design constraints (binding)
Language-design constraints (binding)
The four constraints below are necessary preconditions for RC to be sound and complete without a cycle-collector backstop. The memory model relies on all four:
- Strict evaluation. Every
Term::App(see Data model) argument is fully evaluated before the call. No laziness, no thunks. (Already true.) - No recursive value bindings.
(let x EXPR ...)evaluatesEXPRin a scope wherexis not bound. Recursion is exclusively viaTerm::LetRec(which binds a fn, not a value) and module-level fn defs. (Already true.) - No shared mutable refs. Values are immutable once
constructed. There is no
ref,IORef,Mutex, or any primitive that allows a value to be mutated from a position outside its allocation. (Already true.) - ADTs are acyclic by construction. Strict evaluation + no-recursive-value-bindings + no-shared-mutable-refs together guarantee that any value graph reachable from a binding is a DAG. The reference graph has no cycles. (Follows from 1–3.)
Laziness, recursive value bindings, shared mutable state, or any feature that creates cycles is rejected at design time unless the proposal proves the cycle is collectible by an extension (e.g. linear ownership).
These constraints are the precondition for the memory model: a sound RC implementation without a cycle-collector backstop requires the reference graph to be a DAG, which constraint 4 establishes from 1–3. They are also the load-bearing structural reason behind several rejections under the feature-acceptance bug-class-reintroduction discriminator (notably iterated-mutable-state reasoning).
Guaranteed by construction, not by a positive test: the AST has no
thunk, ref, or IORef node, and (let x EXPR ...) binds x only
in the body, never in EXPR — there is no construct that could
violate constraints 1–3, and constraint 4 follows from them. The
binding force is the design-time
feature-acceptance gate, which rejects
any proposal that would reintroduce one of them.