Skip to content

spec: correct §11.8 — contracts are always emitted regardless of tier (#958)#1023

Merged
aallan merged 4 commits into
mainfrom
fix/958-spec-always-emit-contracts
Jul 13, 2026
Merged

spec: correct §11.8 — contracts are always emitted regardless of tier (#958)#1023
aallan merged 4 commits into
mainfrom
fix/958-spec-always-emit-contracts

Conversation

@aallan

@aallan aallan commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the spec to match code generation (maintainer's decision: keep always-emitting).

Spec §11.8 claimed:

Contracts that the verifier proved (Tier 1) are omitted from the compiled output — they are statically guaranteed and need no runtime check.

That is false, and it contradicted the rest of the same chapter (§11.2: the guards are "type-driven, not tier-driven … emitted at every site regardless of the verifier's tier"). Code generation is tier-agnostic — cmd_compile never calls the verifier and vera/codegen/contracts.py has no notion of tiers — so every non-trivial contract is compiled as a runtime check regardless of the verifier's tier; only trivial contracts (§11.8.1) are eliminated.

This isn't cosmetic. The always-emit guard is the backstop that keeps a false Tier 1 — a verifier proving something it shouldn't, like the still-open #1017 — a loud runtime trap rather than a silent wrong answer. Implementing §11.8's omission optimisation while any false Tier-1 exists would convert every one into a silent miscompile.

Change

  • spec/11-compilation.md §11.8 — corrected to always-emit; the Tier 1 / Tier 3 distinction is reframed as static proof, not code emission, cross-referenced to §11.2 and §11.8.1.
  • TESTING.md — aligned the tier explanation (dropped "no runtime overhead").
  • tests/test_codegen_contracts.py — a differential pin: an ensures(@Int.result == @Int.0) contract verifies Tier-1 (0 Tier-3), yet the compiled WAT still contains the contract_fail guard. Were §11.8's omission ever implemented, this fails loudly — the invariant is now enforced, not just documented.
  • Retired the spec §11.8 says Tier-1-proved contracts are omitted from the compiled output; codegen never sees the tiers and always emits them #958 ROADMAP row; CHANGELOG entry.

Validation

Empirically confirmed before writing the spec: vera verify --json reports the contract tier1_verified (0 Tier-3), and vera compile --wat still emits call $vera.contract_fail + the postcondition trap. check_spec_examples, check_doc_counts, and check_site_assets all green.

Closes #958

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Updated the specification guidance so non-trivial contracts are always compiled into runtime checks, even when statically proved safe.
    • Refreshed clarification in contract verification coverage descriptions.
    • Updated project status, roadmap metrics, and testing/coverage totals.
  • Tests
    • Added a regression test to confirm that Tier 1–proved contracts still emit the expected defensive runtime guard in generated output.

…#958)

Spec §11.8 claimed Tier-1-proved contracts are omitted from the compiled output, contradicting both the rest of the chapter (§11.2's 'type-driven, not tier-driven') and the code (vera/codegen/contracts.py has no notion of tiers). Correct it to always-emit: every non-trivial contract compiles to a runtime check regardless of the verifier's tier; a Tier-1 proof means the check provably never fires, not that it is absent. This is the deliberate backstop that keeps a false Tier-1 (e.g. the open #1017) a loud runtime trap rather than a silent wrong answer. Pin the invariant with a differential test (Tier-1 verify + contract_fail present in the WAT) so the omission cannot be silently introduced; align TESTING's tier explanation; retire the #958 ROADMAP row.

Co-Authored-By: Claude <noreply@anthropic.invalid>
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 1 minute

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f548055d-8cfc-468c-a735-6676b84775fb

📥 Commits

Reviewing files that changed from the base of the PR and between 615a566 and 5cefce3.

📒 Files selected for processing (2)
  • CLAUDE.md
  • tests/test_codegen_contracts.py
📝 Walkthrough

Walkthrough

The change documents tier-agnostic runtime contract emission, adds a Tier-1 regression test confirming the generated guard remains present, updates testing coverage descriptions and counts, and removes the completed roadmap item.

Changes

Contract guard alignment

Layer / File(s) Summary
Tier-1 runtime guard regression
tests/test_codegen_contracts.py
Adds verifier assertions and confirms that a Tier-1-proved contract still generates a contract_fail guard.
Contract insertion semantics
spec/11-compilation.md, TESTING.md, CHANGELOG.md
Documents that non-trivial contracts emit runtime checks independently of verifier tier, while Tier-1 records static proof status.
Project status updates
README.md, ROADMAP.md, TESTING.md
Updates test totals, test-file aggregates, coverage metrics, and removes the completed Stage 19 tracking entry.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested labels: tests, spec, docs

🚥 Pre-merge checks | ✅ 8
✅ Passed checks (8 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main change: correcting §11.8 so non-trivial contracts are always emitted regardless of tier.
Linked Issues check ✅ Passed The spec correction and regression test match #958's requirement that non-trivial contracts remain runtime checks.
Out of Scope Changes check ✅ Passed The changelog, roadmap, and testing doc updates are directly tied to the spec/test changes, with no unrelated code added.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Changelog Covers Public-Surface Changes ✅ Passed Spec §11.8 was updated to always emit non-trivial contract checks, and CHANGELOG.md explicitly describes that public-surface change.
Spec And Implementation Move Together ✅ Passed PASS: No vera/ semantics changed; cmd_compile still skips verify, and contracts.py always emits non-trivial requires/ensures checks, matching updated §11.8.
Diagnostics Carry An Error Code ✅ Passed No new or changed diagnostics appear in the diff; only docs and a codegen regression test were touched, and neither introduces diagnostic fields.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/958-spec-always-emit-contracts

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.51%. Comparing base (c9a9b37) to head (615a566).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1023   +/-   ##
=======================================
  Coverage   93.51%   93.51%           
=======================================
  Files          96       96           
  Lines       32019    32019           
  Branches      456      456           
=======================================
  Hits        29943    29943           
  Misses       2063     2063           
  Partials       13       13           
Flag Coverage Δ
javascript 78.41% <ø> (ø)
python 95.29% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown

Greptile Summary

This PR corrects spec §11.8 to match the actual code generation behaviour: every non-trivial contract is compiled as a runtime check regardless of the verifier's tier, and it adds a differential regression test that pins this always-emit backstop.

  • spec/11-compilation.md §11.8 — rewrites the section to state that code generation is tier-agnostic; Tier 1 now means "the check provably never fires" rather than "the check is omitted", with a cross-reference to §11.2 and §11.8.1.
  • tests/test_codegen_contracts.py — adds test_tier1_proved_contract_still_emits_its_guard_958: verifies that a Tier-1-proved ensures clause (zero Tier-3 obligations) still produces call $vera.contract_fail in the compiled WAT, so any future omission optimisation would fail loudly.
  • CLAUDE.md, CHANGELOG.md, ROADMAP.md, TESTING.md, README.md — documentation and metrics updated consistently (test count 7,404 → 7,405; contract coverage description corrected; spec §11.8 says Tier-1-proved contracts are omitted from the compiled output; codegen never sees the tiers and always emits them #958 ROADMAP row retired; HISTORY.md workflow clarified).

Confidence Score: 5/5

Safe to merge — the change corrects a false spec claim, all doc counters are consistent, and the new regression test correctly pins the always-emit behaviour.

All code changes are either documentation or a single well-scoped regression test. The spec correction is empirically validated in the PR description, existing tests confirm the always-emit path, and the new test adds a differential pin using the established _verify + WAT inspection pattern already present across the suite.

The new test in tests/test_codegen_contracts.py calls _compile instead of _compile_ok, which would produce an opaque assertion failure rather than surfacing compile diagnostics if the source ever stops compiling cleanly.

Important Files Changed

Filename Overview
spec/11-compilation.md §11.8 corrected to always-emit semantics; Tier 1/3 distinction now accurately described as a static-proof classification, not a code-emission gate.
tests/test_codegen_contracts.py Adds regression test pinning always-emit backstop for Tier-1-proved contracts; uses _compile instead of _compile_ok, which would obscure diagnostics on a compile failure.
CLAUDE.md Release workflow clarified: HISTORY.md one-liners are added at release-cut time, not in the issue-closing PR; speculative pending rows explicitly prohibited.
CHANGELOG.md Documentation section added under [Unreleased] for the §11.8 spec correction; entry is accurate and well-referenced.
TESTING.md Test count updated to 7,405 (7,309 passed + 26 stress + 70 skipped); contract verification coverage description updated to reflect always-emit semantics.
ROADMAP.md Removes the closed #958 entry and updates test count; consistent with project workflow.
README.md Test count updated from 7,404 to 7,405 to reflect the new regression test.

Reviews (3): Last reviewed commit: "docs: correct the HISTORY-one-liner timi..." | Re-trigger Greptile

Comment thread ROADMAP.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_codegen_contracts.py`:
- Line 595: Update the assertion in the relevant code-generation contract test
to verify the emitted instruction `call $vera.contract_fail`, rather than only
searching for the `contract_fail` symbol name. Use a boundary-safe exact
instruction match against the WAT returned by `_compile(src).wat`, ensuring
imports alone cannot satisfy the test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 080b3064-691c-41ae-827b-a8c7c6fca81e

📥 Commits

Reviewing files that changed from the base of the PR and between c9a9b37 and 3670351.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • README.md
  • ROADMAP.md
  • TESTING.md
  • spec/11-compilation.md
  • tests/test_codegen_contracts.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • aallan/vera-bench (manual)

Comment thread tests/test_codegen_contracts.py Outdated
aallan and others added 3 commits July 13, 2026 18:27
CodeRabbit flagged that `"contract_fail" in wat` also matches the always-present import declaration, so the differential could pass even if the guard call were omitted. Assert the exact `call $vera.contract_fail` instruction (boundary-safe, one line stripped) so the pin genuinely fails if the tier-omission were ever implemented.

Co-Authored-By: Claude <noreply@anthropic.invalid>
…e review)

The `contract_fail` host import is lazy — emitted only when a guard is
actually called — so the prior comment's claim that "a substring check would
pass on the import alone" was inaccurate: with no call there is no import
either. Reworded to state the real reason for asserting the exact
`call $vera.contract_fail` instruction: a direct check that the guard is
invoked, rather than a substring match on the symbol.

Co-Authored-By: Claude <noreply@anthropic.invalid>
CLAUDE.md said to add a HISTORY.md one-liner "when an issue is closed by a
PR", which mandates a row this PR (riding [Unreleased]) does not add and
which Greptile flagged. The doc was wrong, not the PR: HISTORY version-rows
are written at release-cut time, keyed to a shipped vX.Y.Z. A fix riding
CHANGELOG [Unreleased] is recorded there and rolls into the HISTORY row when
the version is tagged. Clarify the rule and warn against the speculative
"Pending" row that was reverted on #1020.

Co-Authored-By: Claude <noreply@anthropic.invalid>
@aallan aallan merged commit 1d3c9df into main Jul 13, 2026
24 checks passed
@aallan aallan deleted the fix/958-spec-always-emit-contracts branch July 13, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spec §11.8 says Tier-1-proved contracts are omitted from the compiled output; codegen never sees the tiers and always emits them

1 participant