Kida 0.12.0

Programmatic diagnostics, literal block metadata, and deeper free-threading proof

Released 2026-07-13.

Kida 0.12.0 gives frameworks and developer tools stronger compile-time facts. Blocks and fragments can carry typed literal metadata, diagnostics have a public programmatic model with JSON and SARIF surfaces, and safe edits can be applied only when their source snapshot still matches. The release also expands Kida's Python 3.14t evidence and keeps the runtime dependency-free.

Added

Literal block and fragment metadata

  • Framework-owned modifiers{% block chart enhanced="sse" fallback="table" %} and {% fragment updates transport="sse" %}attach ordered literal metadata to existing render units.
  • Typed, source-located introspectionBlockMetadata.modifierscontains immutableBlockModifierMetadatarecords with scalar values and exact declaration locations.get_modifier()provides direct lookup.
  • Compile-time rejection — Duplicate names, dynamic expressions, collections, and malformed assignments fail during parsing. Kida validates the generic shape only; frameworks own their supported vocabulary.
  • No render or cache drift — Modifiers do not alter rendered bytes, dependency analysis, inheritance, composition, or structural block hashes.

Programmatic diagnostics

  • Public diagnostic modelkida.diagnosticsexposes immutable findings, source spans, confidence, related locations, snippets, and reports for editors and framework adapters without giving policy decisions to the model.
  • Unsaved-source diagnosisdiagnose_source()analyzes an editor buffer directly, whilediagnose_directory() matches kida checkcollection.
  • Machine-readable CLI outputkida check --format text, json, and sarifshare one deterministic, deduplicated collection and preserve the existing0 / 1 / 2exit policy.
  • Verified safe edits — Strict unified closers can carry exact replacements. apply_safe_edits()rejects stale, incomplete, and overlapping edits before changing source; advisory migrations remain non-fixing.
  • Extension diagnostics — NamespacedExtension.diagnose()hooks receive immutable source, AST, and visible-component metadata. Invalid ownership, locations, or snapshots are rejected, and extension failures make the report partial instead of breaking rendering.

Migration and downstream evidence

  • Block-sensitive Jinja migration warning — K-WARN-002 now detects a {% set %} binding read after an if, including nested branches, named blocks, and later reads in the same loop iteration.
  • Pinned downstream canaries — Report-only chirp-ui and Milo jobs prove their Kida source override, run on Python 3.14t withPYTHON_GIL=0, and keep public-fork permissions read-only.

Changed

  • Release-note collection is typed — GitHub PR collection follows pagination, validates its report contract, and fails explicitly for malformed responses and invalid ref ranges.
  • CLI phases are smaller — Argument parsing, lazy dispatch, execution, and presentation moved into command-owned modules behind the unchanged kida.cli:mainentry point.
  • Compiler phases are explicit — Lowering, callable plans, block variants, analysis, and partial-evaluation tests are split into focused modules while retaining generated-output and render-surface parity.
  • Free-threading claims link evidence — Public docs name the no-GIL PR lane, scheduled seeded stress window, stable loader-source boundary, and read-only metadata boundary.

Fixed

  • Shared analyzers isolate traversal state — Concurrent analysis no longer shares mutable walker state across calls.
  • Migration warnings match Jinja scope — Outer-name shadows inside non-scopingif blocks warn; loop-local forassignments no longer produce the same false positive.
  • Live updates serialize publication — Terminal live rendering protects shared update state on free-threaded builds.
  • Streaming block fallbacks stay intact — Error boundaries inside named blocks preserve fallback behavior on synchronous and asynchronous surfaces.

Upgrade Notes

  1. No existing template needs to add modifiers. Unannotated block and fragment syntax compiles and renders as before.
  2. Frameworks should readBlockMetadata.modifiers; do not parse template source or comments as a parallel metadata channel.
  3. Modifier values are literal strings, integers, floats, booleans, orNone. Put runtime decisions in template expressions or framework code instead.
  4. Consumers that snapshotkida.__all__ or BlockMetadatafields should add BlockModifierMetadata and modifiers.
  5. Diagnostic consumers should branch on stable codes and structured fields, not rendered terminal wording.

Downstream checkpoint

Chirp's adapter pilot failed on Kida 0.11 because modifier syntax could not compile and passed against the 0.12 candidate with typed block/fragment metadata plus byte-identical full and block rendering. Chirp still owns its enhancement vocabulary, fallback graph, severity policy, and browser-level no-JavaScript proof; Kida does not assign those semantics.