You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Audit during PR #650 surfaced ~10 spec sites where the documented language behaviour is in tension with the stated design principles in §0.2 ("Explicitness") and §0.2.3 / §0.3.2 ("One canonical form / no shorthand / no implicit conversions / no default arguments").
Each item is individually defensible as a deliberate ergonomic tradeoff, but the principles as currently written claim absoluteness ("There is no implicit behaviour for the model to infer or hallucinate") that the spec then partly contradicts in later chapters. The result is a spec that's internally inconsistent on its own foundational rules.
Drift inventory
#
Site
Tension
Severity
A
spec/09-standard-library.md §9.1.2
"Every Vera program implicitly has access to a standard prelude" — Option<T>, Result<T, E>, Ordering, UrlParts, combinators, array operations available without declaration.
High — most foundational implicit surface in the language.
B
spec/01 §1.7 + spec/04 §interpolation
Non-String types in \(...) "automatically converted to String". Defended in §4 as "InterpolatedString is the canonical form — the interpolation syntax IS the explicit marker"; arguably defensible.
Medium
C
spec/02-types.md §2.5
"A function type with no effects annotation defaults to effects(pure)." §0.3.2 explicitly bans "default arguments".
Medium
D
spec/05-functions.md §5.4
"Multiple requires clauses are equivalent to a single requires with &&." Two textual forms for the same constraint — direct violation of §0.2.3 "no equivalent alternatives".
Medium
E
spec/03-slot-references.md §3.7
@Fn<A,B>.0 documented as "shorthand for the function argument". §0.3.2 explicitly bans "shorthand syntax". Needs investigation of whether this is shorthand or actually the only form.
Medium
F
spec/09 ability auto-derivation
"If all fields of an ADT support Eq, the ADT supports Eqautomatically." Auto-derivation across Eq / Ord / Hash / Show.
Medium
G
spec/09 State.get()
"State<T>.get() — the Unit parameter is implicit."
Low (single built-in)
H
spec/07-effects.md §7.5 IO
IO operations "available automatically when effects(<IO>) is specified" — programs don't declare effect IO { ... }. The IO effect is hard-wired; all other effects are user-declared.
Medium
I
spec/07-effects.md §7.5 resume
"Operations implicitly have access to the resume continuation" in handler arms. Implicit name binding.
Low (handler-local)
J
spec/08-modules.md §8.2
"Every module may optionally declare its identity with a module statement". §0.2.3 bans optional syntax.
Low (parser flexibility)
K
spec/02-types.md §2.2.1 (new)
Int <: Nat flows without explicit cast (verifier-mediated). Partly mitigated by reframing wording in PR #650 from "implicit" → "syntactically silent but semantically verified", anchored to "verification is a first-class citizen" exception.
Low (verifier-checked)
Proposed resolution shape
Two options, not mutually exclusive:
Option 1 — Strengthen §0.3 to enumerate the deliberate implicit surfaces
Add a §0.3.6 or similar:
Implicit surfaces excluded from §0.2.2 — the following are deliberate exceptions where the cost of explicitness outweighs the principle benefit:
The standard prelude (§9.1.2) — Option, Result, Ordering, UrlParts, and their associated combinator and accessor functions are available without declaration.
The IO effect (§7.5) — operations are available when effects(<IO>) is declared, without a user-side effect IO { ... } declaration.
The resume continuation (§7.5) — implicitly bound inside handler arms.
Ability auto-derivation (§9.X) — built-in abilities (Eq, Ord, Hash, Show) are derived automatically for ADTs whose fields support them.
Primitive-to-String coercion inside InterpolatedString (§1.7) — primitive types (Int, Nat, Bool, Byte, Float64) are wrapped via *_to_string automatically; the interpolation syntax \(...) is the explicit marker.
effects(pure) default on function-type annotations (§2.5) — type-level annotation only; function declarations still require an explicit effects(...) clause.
Verifier-mediated subtyping (§2.2.1) — Int <: Nat is accepted at type-check time but the verifier discharges an obligation; the conversion is syntactically silent but semantically verified.
State<T>.get() Unit-arg elision (§9.X) — single built-in exception.
This makes the principle honest. The cost is acknowledging the design has 8 narrowly-scoped exceptions; the benefit is that the spec no longer contradicts itself.
Option 2 — Triage each item separately
Some of the "exceptions" above may not be defensible on inspection:
D (multiple requires equivalence) — the "one canonical form" violation here is real. The justification ("more precise error reporting") could instead be solved by a different mechanism (e.g., named requires clauses) without two textual forms.
E (@Fn<A,B>.0 shorthand) — needs investigation. If @Fn<A,B>.0 is the only way to refer to the function argument (and the word "shorthand" is misleading), §3.7 should be reworded. If there's an alternative long form, one of the two should be deprecated.
J (optional module statement) — §10 grammar already marks visibility as parser-flexible-but-checker-mandatory. The module statement could do the same: parser accepts both forms, but a future linter/vera fmt could enforce one canonical shape.
Items where the implicit-ness is genuinely load-bearing (A, B, F, H, I, K) get enumerated in §0.3 via Option 1. Items where the implicit-ness is just unfixed legacy (D, E, J) get individual close-out PRs.
Recommendation
Both. Start with Option 1 (§0.3 enumeration) as one PR — honest framing, no behaviour change. Then file 3 follow-up issues for D, E, J as separate triage candidates.
Why this matters
LLMs reading the spec take §0.2.2 literally ("there is no implicit behaviour"). When the same model then writes a Vera program that depends on prelude Option or auto-derived Eq, it experiences a contradiction with the principle as it understood it. The honest framing reduces this confusion — "the language has X implicit surfaces, here they are, expect them" is better than an absolute claim that the rest of the spec quietly walks back.
Source
Audit performed 2026-05-11 during PR #650 review pass.
Related
PR Small docs sweep: #557 + #561 + #560 + #607 + #608 + #512 #650 — addressed item K (the §2.2.1 Int↔Nat wording) by reframing "implicitly" → "syntactically silent but semantically verified". This is the model fix for how to discuss verifier-mediated subtyping; could be extended to other items.
Summary
Audit during PR #650 surfaced ~10 spec sites where the documented language behaviour is in tension with the stated design principles in §0.2 ("Explicitness") and §0.2.3 / §0.3.2 ("One canonical form / no shorthand / no implicit conversions / no default arguments").
Each item is individually defensible as a deliberate ergonomic tradeoff, but the principles as currently written claim absoluteness ("There is no implicit behaviour for the model to infer or hallucinate") that the spec then partly contradicts in later chapters. The result is a spec that's internally inconsistent on its own foundational rules.
Drift inventory
spec/09-standard-library.md§9.1.2Option<T>,Result<T, E>,Ordering,UrlParts, combinators, array operations available without declaration.spec/01§1.7 +spec/04§interpolation\(...)"automatically converted to String". Defended in §4 as "InterpolatedString is the canonical form — the interpolation syntax IS the explicit marker"; arguably defensible.spec/02-types.md§2.5effects(pure)." §0.3.2 explicitly bans "default arguments".spec/05-functions.md§5.4requiresclauses are equivalent to a singlerequireswith&&." Two textual forms for the same constraint — direct violation of §0.2.3 "no equivalent alternatives".spec/03-slot-references.md§3.7@Fn<A,B>.0documented as "shorthand for the function argument". §0.3.2 explicitly bans "shorthand syntax". Needs investigation of whether this is shorthand or actually the only form.spec/09ability auto-derivationEq, the ADT supportsEqautomatically." Auto-derivation acrossEq/Ord/Hash/Show.spec/09State.get()State<T>.get()— theUnitparameter is implicit."spec/07-effects.md§7.5 IOeffects(<IO>)is specified" — programs don't declareeffect IO { ... }. The IO effect is hard-wired; all other effects are user-declared.spec/07-effects.md§7.5 resumeresumecontinuation" in handler arms. Implicit name binding.spec/08-modules.md§8.2modulestatement". §0.2.3 bans optional syntax.spec/02-types.md§2.2.1 (new)Int <: Natflows without explicit cast (verifier-mediated). Partly mitigated by reframing wording in PR #650 from "implicit" → "syntactically silent but semantically verified", anchored to "verification is a first-class citizen" exception.Proposed resolution shape
Two options, not mutually exclusive:
Option 1 — Strengthen §0.3 to enumerate the deliberate implicit surfaces
Add a §0.3.6 or similar:
This makes the principle honest. The cost is acknowledging the design has 8 narrowly-scoped exceptions; the benefit is that the spec no longer contradicts itself.
Option 2 — Triage each item separately
Some of the "exceptions" above may not be defensible on inspection:
requiresequivalence) — the "one canonical form" violation here is real. The justification ("more precise error reporting") could instead be solved by a different mechanism (e.g., named requires clauses) without two textual forms.@Fn<A,B>.0shorthand) — needs investigation. If@Fn<A,B>.0is the only way to refer to the function argument (and the word "shorthand" is misleading), §3.7 should be reworded. If there's an alternative long form, one of the two should be deprecated.modulestatement) — §10 grammar already marks visibility as parser-flexible-but-checker-mandatory. Themodulestatement could do the same: parser accepts both forms, but a future linter/vera fmtcould enforce one canonical shape.Items where the implicit-ness is genuinely load-bearing (A, B, F, H, I, K) get enumerated in §0.3 via Option 1. Items where the implicit-ness is just unfixed legacy (D, E, J) get individual close-out PRs.
Recommendation
Both. Start with Option 1 (§0.3 enumeration) as one PR — honest framing, no behaviour change. Then file 3 follow-up issues for D, E, J as separate triage candidates.
Why this matters
LLMs reading the spec take §0.2.2 literally ("there is no implicit behaviour"). When the same model then writes a Vera program that depends on prelude
Optionor auto-derivedEq, it experiences a contradiction with the principle as it understood it. The honest framing reduces this confusion — "the language has X implicit surfaces, here they are, expect them" is better than an absolute claim that the rest of the spec quietly walks back.Source
Audit performed 2026-05-11 during PR #650 review pass.
Related