# Kida 0.9.0

URL: /kida/releases/0.9.0/
Section: releases
Description: Large-app analysis APIs, report contract hardening, Markdown escaping fixes, and release-gate cleanup

---

> For a complete page index, fetch /kida/llms.txt.

# v0.9.0

**Released** 2026-05-10.

Kida 0.9.0 is a large-app ergonomics and release-hardening release. It adds route-agnostic static analysis helpers for context contracts, literal attributes, escape audits, and privacy linting; stabilizes component catalog metadata; hardens report-template contracts across Markdown/GitHub/AMP surfaces; and fixes the Markdown autoescape behavior that made CI reports and release notes too noisy.

## Breaking

- **Markdown autoescape is less noisy** — `autoescape="markdown"` no longer backslash-escapes inline hyphens, parentheses, hashes, pipes, or tildes when those characters do not trigger Markdown formatting. Prose, dates, version numbers, diagnostic codes, and function-call text now render cleanly: `2026-05-10`, `K-PAR-001`, and `divide(1, 0)` stay readable.
- **`Markup` is safe in Markdown mode** — `{{ value | safe }}` returns `Markup`, and `Markup` now implements `__markdown__`. Markdown autoescape treats that as trusted content, matching the existing HTML `__html__` behavior.

## Added

### Large-app analysis facts

- **Context contracts** — `kida.analysis.check_context_contract()` compares what a template reads against a framework or route-provided context contract. It returns structured `K-CTX-001` missing-context errors and `K-CTX-002` unused-context warnings.
- **Literal attributes** — `kida.analysis.extract_literal_attributes()` extracts static HTML attributes such as `id`, `data-*`, or framework target attributes with template name and source position. Dynamic attributes are intentionally not inferred.
- **Escape audit** — `kida.analysis.audit_escaping()` reports escaped output sites, unescaped output, disabled autoescape blocks, `| safe` usage with optional `reason=`, and trusted-markup filters such as `tojson` and `xmlattr`.
- **Privacy lint** — `kida.analysis.lint_privacy()` flags sensitive-looking dependency paths, secret-like literals, broad context/debug output, `| safe` on sensitive-looking values, and dynamic template names. Secret-like values are not echoed in diagnostics.

### Component and report contracts

- **Component catalog metadata** — Component metadata and `kida components --json` now expose more stable fields for dependencies, source locations, call sites, and slot/default information, with snapshot and diagnostics tests.
- **Report template contract manifest** — `docs/report-template-contracts.json` records built-in report templates, fixtures, snapshots, target surfaces, and AMP schema mappings.
- **Report readability and schema tests** — Built-in report templates now have explicit manifest, AMP schema, GitHub report, snapshot, and readability tests so drift across CI comments, step summaries, release notes, and terminal outputs is caught earlier.

### Examples and stewardship

- **Review packet example** — New example code renders a structured review packet across Markdown and terminal surfaces.
- **Refactor-safety example** — New example fixtures show fragile include paths, component call validation, and refactor-safe template organization.
- **Scoped steward files** — Root and scoped `AGENTS.md` files now document steward responsibilities for parser/compiler/runtime/analysis/docs/tests/templates/schemas/workflows, giving future review work clearer local invariants.

## Changed

- **Large-app analysis docs** — Advanced analysis docs now describe context contracts, component catalogs, literal attribute extraction, escape audits, privacy linting, and review-packet inspection.
- **Benchmark scripts use the project runner** — Benchmark baseline/compare scripts prefer `uv run python` and accept `PYTHON_CMD=...`, which avoids stale global pytest/plugin environments during release gates.
- **Docs and README positioning** — Public docs and examples now better describe Kida’s component model, static validation, render-surface parity, and free-threading goals.

## Fixed

- **Release-note PR bodies render as Markdown** — Built-in `release-notes` templates mark PR `body_excerpt` and `body` fields safe, so headings, lists, and inline code in PR bodies render as authored instead of appearing as escaped literals inside `<details>` blocks.
- **Fragment render contracts** — Sync/async block rendering and `render_with_blocks` now preserve metadata and fragment behavior more consistently across composition surfaces.
- **List-shaped report JSON** — `kida render` report flows now handle JSON files whose top-level value is a list, which matches real tool output for several CI report shapes.
- **Fragile-path lint stale-cache crash** — The bytecode cache no longer leaves fragile-path lint vulnerable to stale optimized-AST entries after template source changes.
- **Docs build health** — The release collateral now includes a 0.9.0 release page and clean docs-health links.

## Upgrade Notes

1. **Regenerate Markdown snapshots** — If you commit snapshots for templates rendered with `autoescape="markdown"` or `markdown_env()`, rerun the snapshot command for that suite. Expected output should lose unnecessary backslashes.
2. **Audit `| safe` in Markdown templates** — `safe` now bypasses Markdown escaping. Keep it only for content already sanitized, generated by trusted tooling, or intentionally authored as Markdown.
3. **Try the new analysis helpers behind framework checks** — The context, literal-attribute, escape, and privacy helpers are route-agnostic facts. Frameworks should layer their own route/request semantics on top.
4. **Check component catalog consumers** — If you parse `kida components --json`, review the added metadata fields and keep snapshot tests around your consumer.
5. **Do not use `safe` for untrusted issue, PR, or tool output** — CI inputs can contain Markdown that hides content, changes tables, or creates misleading links. Let Markdown autoescape handle untrusted strings.
6. **Pin if needed** — `pip install 'kida-templates==0.8.*'` keeps the previous Markdown escaping behavior while you update snapshots and review `safe` usage.

## Why this change

Kida is increasingly used inside larger server-rendered applications and CI/reporting workflows. Those consumers need facts they can validate before render: which context paths a template reads, which components exist, which static attributes are present, where escaping happens, and which outputs may expose private data. Kida 0.9.0 keeps those facts route-agnostic so frameworks can compose them without Kida learning framework-specific routing semantics.

Kida's old Markdown escaping also protected too much by escaping punctuation that CommonMark/GFM does not treat as formatting in normal inline text. That made generated reports harder to read and polluted release notes with backslashes. The new behavior keeps escaping for real Markdown triggers while preserving literal prose and diagnostic text.

The `safe` change closes a surface-parity gap: safe strings were honored under HTML autoescape, but not under Markdown autoescape. That inconsistency made built-in report templates unable to intentionally pass trusted Markdown through without awkward workarounds.
