Project Contract Change v1
September 10, 2026 ยท View on GitHub
Audience: agent builders, compiler contributors, and reviewers.
Status: implemented bounded profile; HOSTED GREEN under the v0.4.0 release baseline. Historical local, authoring-time, ignored, or separately provisioned observations below retain their narrower scope; public promotion and broader product completion remain separately gated.
The additive add_contract intention appends exactly one typed predicate to
an explicit, monomorphic, top-level non-main function in an immutable
Project Candidate. It grants no source publication
or execution authority and introduces no new source-language syntax.
Intention and context
The object has exactly kind, target, phase, and predicate:
{
"kind": "add_contract",
"target": "calculator.divide",
"phase": "requires",
"predicate": {
"kind": "binary",
"op": ">=",
"left": {"kind": "place", "name": "left"},
"right": {"kind": "i64", "value": 0}
}
}
phase is requires or ensures. Predicates use the existing bounded typed
expression constructors. Function parameters are in scope; the compiler's
result binding is additionally available only in ensures. Local body
bindings are unavailable. Calls must resolve through existing local/import
stable-ID bindings; this operation cannot add imports, effects or capabilities.
The ordinary verifier decides boolean typing, contract purity, allowed call semantics, ownership, loans and cleanup. A syntactically valid JSON object is not a validation receipt. Adding a precondition may restrict valid inputs; adding a postcondition may introduce runtime contract failure. Full candidate admission does not prove all executions satisfy the new predicate or establish external API compatibility.
Preservation and replay
The transformation retains every existing predicate in its original order and appends one new predicate to the selected phase. Candidate invariant comparison permits exactly the corresponding count increment for that target; all other contract inventories, declared effects and module permits remain unchanged. The existing explicit identity and manifest/export guards still apply. Neither removing nor replacing an old predicate is supported here.
A separate Contract Expression Change
intention can replace a selected authored subtree in an existing predicate,
with exact source reconstruction and expected-type/ownership checks. It does
not change the append-only behavior of add_contract.
Canonical source is generated in memory and reparsed. Complete Project rebuilding links callers and revalidates contracts, ownership, cleanup and the selected profile. Independent source replay must reproduce the exact Project revision and graph. Previously admitted native C11 and structurally validated Core-Wasm projection lanes must remain admitted. No target or test execution occurs during candidate admission.
Changes, graph digests, structural impact and source diffs use the existing candidate evidence envelope. The exact typed predicate remains in the ordered change history for independent replay. Source files and sibling candidates stay unchanged on success, stale input or failure.
Bounds and evidence
The function's combined pre/postcondition count must be below 1024 before an
addition. Existing change bytes, expression depth/node, 32-intention history,
canonical source, Project and target bounds remain in force. Bad phases,
unknown fields or illegal constructor scope reject with SPX-G225; contract
inventory capacity rejects with SPX-G226. Type/purity/ownership failures use
the ordinary compiler diagnostic. Exact candidate and Project digest checks
continue to reject stale changes before transformation.
Release-tested cases in tests/project_candidate/candidates.rs cover ordered
preservation of an existing precondition, additive postconditions using
result, exact replay, no writes, invalid phase/scope, and non-boolean
rejection. The implemented corpus is HOSTED GREEN; the broader product goal remains Partial.