Skip to content

NTNT v0.5.0 — verification release

Latest

Choose a tag to compare

@github-actions github-actions released this 09 Jul 01:29
8e15af2

NTNT v0.5.0 Release Notes

v0.5.0 is the verification release. The DD-063 language assessment is fully closed — every silent failure it identified is now loud, the agent repair loop reports everything the error infrastructure can express, and verification commands verify under strict semantics by default. Alongside it: the two most-requested stdlib modules (std/validate, std/email), a hardened multi-worker runtime, and the last web-app quick wins.

Highlights

  • Declarative validation (std/validate)

    • schema(map { field: [rules...] }) + validate(schema, data)Ok(cleaned) with coerced values (unknown keys dropped) or Err(field → message).
    • Rules compose validators (required, optional, email, url, min_value/max_value, min_length/max_length, one_of, matches, default), the global conversion functions int/float/bool/str (and std/string trim) for coercion, and bare fn(value) closures as custom predicates.
    • Fields are required by default; optional permits absence, default(v) supplies a value that still runs the remaining rules.
  • Email sending (std/email)

    • configure_email(...) once at startup; send_email(...)Ok(map { "message_id", "transport" }) or Err(message) — bad addresses and SMTP failures are values, never crashes.
    • send_email_batch([...]) reuses one pooled connection with per-email results; one bad email never stops the rest.
    • A log transport ("transport": "log", or NTNT_EMAIL_MODE=log) prints emails to stderr and reports them sent — development and CI run the full email path with no SMTP server.
    • TLS defaults from the port (465 implicit, others STARTTLS); rustls, no openssl.
  • The agent repair loop, completed (DD-063)

    • ntnt lint/validate/check recover from parse errors and report up to 5 per file in one pass; semantic checks are suppressed on partial ASTs.
    • Contract violations (E004) show the failing clause's source frame, the actual runtime values (where: b = 0), and the call site.
    • Unknown method calls get did-you-mean plus a UFCS bridge hint (try len(s)); new lint rules unknown_method, block_binding, and static_contract_violation (calls with literal arguments that provably violate a requires clause are flagged at lint time).
    • IAL unknown terms get near-miss suggestions; new ntnt intent lint statically validates glossaries and scenarios (unresolved terms, definition cycles, vacuous scenarios, orphan entries) with --json for CI — no server startup.
    • Fixed a false-assurance bug: intent files declaring invariants before features silently lost their feature ids and scenario outcomes, letting scenarios pass while verifying nothing.
  • Runtime and workers

    • Array/string out-of-bounds reads are loud by type mode: [WARN] + None in warn, error E010 in strict, silent in forgiving. Map missing-key access stays silent-None by design; arr[i] ?? default, arr[i]?, and otherwise suppress the diagnostics entirely.
    • Crashed HTTP workers are supervised and respawned with backoff; ntnt run --workers N joins NTNT_WORKERS.
    • Verified under benchmark: 8 workers take the TechEmpower-style single-query workload from 8.3K to 39K req/s.
  • Quick wins

    • paginate(total, page, per_page) (std/collections) — offset/limit/pages/flags with safe clamping.
    • from_now(ts) / time_ago(ts) (std/time) — "3 hours ago", "in 2 days", "just now".

Behavior changes

  • Verification defaults to strict type mode. ntnt test and ntnt intent check run with NTNT_TYPE_MODE=strict when the variable is unset — degradations that warn mode tolerates (out-of-bounds → None, implicit conversions) now fail verification. Set NTNT_TYPE_MODE=warn explicitly to restore the old tolerance. ntnt run is unchanged.
  • Strict mode errors on out-of-bounds reads. Code run under NTNT_TYPE_MODE=strict that previously tolerated OOB-as-None now stops with E010. Guarded access (??, ?, otherwise) is exempt.
  • is_some/is_none/is_ok/is_err/unwrap_or are arity-checked at lint time; wrong-arity calls that previously passed silently now report.
  • Lint JSON: a file with N parse errors contributes N to summary.errors (previously 1); parse errors now include column. ntnt parse --json: contract clauses serialize as {expression, line} objects.
  • Scheduled loops and multi-worker: no change — module-level schedule() loops are capability-gated and run exactly once, on the primary interpreter; Worker-mode interpreters skip them (same as listen()).

Docs

  • The whitepaper now separates shipped capability from aspiration in a prominent Implementation Status section.
  • IAL reference documents invariant expansion honestly (the never-implemented Sql/InvariantCheck primitives are removed).
  • Agent guide: indexing semantics, validation, email, worker parallelism, intent lint workflow.

Upgrade notes

If your CI runs ntnt test or ntnt intent check and relied on warn-mode tolerance, either fix the surfaced issues (recommended — they are real) or set NTNT_TYPE_MODE=warn for the affected jobs. Consumers of lint/parse JSON should adopt the new summary.errors counting and contract-clause shapes.