Skip to content

Commit 23d1cd4

Browse files
authored
[codex] prepare 0.10.0 release (#133)
1 parent 66cf8ec commit 23d1cd4

10 files changed

Lines changed: 389 additions & 31 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.10.0] - 2026-05-30
11+
12+
### Added
13+
14+
- **Structured undefined diagnostics for framework debug views**`UndefinedError.to_diagnostic()` now returns a surface-neutral payload with error code, kind, location, source snippet, ordered hints, docs URL, metadata, template stack, and component stack. The diagnostic can render escaped HTML fragments/pages or GitHub-flavored Markdown without frameworks parsing terminal-formatted exception strings.
15+
16+
### Fixed
17+
18+
- **Undefined-error source attribution survives optimized rendering paths** — F-string coalescing now preserves the template line marker used by diagnostics, so optimized templates still report the editable source line.
19+
- **Imported component slot failures point at caller-owned source** — Errors raised inside slot bodies provided to imported components now attribute the primary diagnostic location to the caller template while retaining component-stack context.
20+
- **Streaming runtime errors use the same template-enhanced diagnostics as full render** — Generic Python exceptions raised during `render_stream()` are wrapped with template name and line information consistently with `render()`.
21+
1022
## [0.9.0] - 2026-05-10
1123

1224
### Breaking

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,9 @@ for the Mapping behavior change in null-safe access (`?.` and `?[...]`).
346346
Moving from 0.8.x? See the [0.9 release notes](https://lbliii.github.io/kida/releases/0.9.0/)
347347
for the Markdown escaping and `| safe` trust-boundary changes.
348348

349+
Moving from 0.9.x? See the [0.10 release notes](https://lbliii.github.io/kida/releases/0.10.0/)
350+
for structured diagnostics and source-attribution hardening.
351+
349352
## The Bengal Ecosystem
350353

351354
Kida is part of a pure-Python stack built for 3.14t free-threading.

plan/release-0.10.0-roadmap.md

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
# Release Roadmap: Kida 0.10.0
2+
3+
**Status**: Release branch candidate prepared; final local gates passed; publishing not performed
4+
**Created**: 2026-05-30
5+
**Target theme**: Structured diagnostics and release-readiness hardening
6+
**Baseline**: `origin/main` at `66cf8ec` (`[codex] Improve UndefinedError diagnostics for framework views (#132)`)
7+
8+
## Objective
9+
10+
Ship the post-0.9.0 structured diagnostics work as a focused 0.10.0 release,
11+
without mixing in new syntax, new runtime dependencies, new schema versions, or
12+
large-app ergonomics features that still need separate approval.
13+
14+
## Research Basis
15+
16+
- Initial audit found `pyproject.toml` at `0.9.0`; release prep now updates the
17+
project metadata and lockfile to `0.10.0`.
18+
- Initial local audit before fetching remote state found six post-`v0.9.0`
19+
diagnostics commits: structured undefined diagnostics, preserved undefined
20+
attribution, render surface diagnostic parity, a standalone diagnostic HTML
21+
page, public docs, and the coalescing line-marker contract. Remote `main` now
22+
carries that work as squash commit `66cf8ec` from PR #132, so the release
23+
branch is based on current `origin/main` instead of replaying the pre-squash
24+
local history.
25+
- Focused diagnostics tests pass, and `make lint` / `make ty` are clean on the
26+
current baseline.
27+
- `CHANGELOG.md` initially had an empty `[Unreleased]` section; release prep now
28+
includes a dated `0.10.0` changelog entry and published release-page source.
29+
30+
## Steward Signals
31+
32+
### Planning
33+
34+
- Steward: Planning
35+
- Area: Release scope
36+
- Severity: P1
37+
- Invariant: Plans sequence real work and do not smuggle stop-and-ask changes.
38+
- Evidence: The active commits are diagnostics-only; large-app ergonomics is
39+
still proposed and contains public API/open-question items.
40+
- User Impact: A focused release is reviewable and avoids making unrelated
41+
promises.
42+
- Required Fix: Treat 0.10.0 as diagnostics hardening; defer new validation
43+
APIs, schemas, and framework policies.
44+
- Required Proof: Changelog entry, roadmap record, focused tests, lint, and ty.
45+
- Collateral: `CHANGELOG.md`, docs pages touched by diagnostics.
46+
- Confidence: High
47+
48+
### Runtime
49+
50+
- Steward: Runtime
51+
- Area: Exception contracts
52+
- Severity: P1
53+
- Invariant: Public errors preserve template names, source locations, hints, and
54+
zero-dependency rendering helpers.
55+
- Evidence: `UndefinedError.to_diagnostic()` exposes location, snippets, hints,
56+
stacks, docs URL, and escaped HTML/Markdown renderers.
57+
- User Impact: Framework debug pages can stop scraping terminal-formatted text.
58+
- Required Fix: Do not export new top-level diagnostic dataclasses in this
59+
release unless explicitly approved; document the current method-based access.
60+
- Required Proof: `tests/test_diagnostics_contract.py` and public API snapshot.
61+
- Collateral: Error handling and undefined-variable docs.
62+
- Confidence: High
63+
64+
### Template Runtime
65+
66+
- Steward: Template Runtime
67+
- Area: Render-mode diagnostic parity
68+
- Severity: P1
69+
- Invariant: Full render, streaming, imported components, and slot caller bodies
70+
attribute failures to the template line users can edit.
71+
- Evidence: Existing focused tests cover coalesced output source lines, imported
72+
slot errors, component stacks, streaming runtime enhancement, HTML pages, and
73+
Markdown diagnostics.
74+
- User Impact: Users debugging generated code see actionable template source,
75+
not misleading Python frames.
76+
- Required Fix: Keep diagnostic tests in the release gate; add more render-mode
77+
parity only if failures appear.
78+
- Required Proof: Focused diagnostics suite and full test/coverage gate.
79+
- Collateral: Troubleshooting docs mention caller-template attribution for slots.
80+
- Confidence: High
81+
82+
### Compiler
83+
84+
- Steward: Compiler
85+
- Area: F-string coalescing source locations
86+
- Severity: P1
87+
- Invariant: Hot-path coalescing must not erase source mapping.
88+
- Evidence: `fix: declare coalescing line marker contract` plus a test asserting
89+
undefined diagnostics remain on the correct template line with coalescing on.
90+
- User Impact: Optimized templates remain debuggable.
91+
- Required Fix: No further compiler optimization in this release without
92+
benchmark or explicit no-benchmark rationale.
93+
- Required Proof: Existing coalescing diagnostic test; no benchmark required for
94+
source-map-only hardening.
95+
- Collateral: Changelog names the source-location fix.
96+
- Confidence: Medium-high
97+
98+
### Static Analysis
99+
100+
- Steward: Static Analysis
101+
- Area: Diagnostic/code contract
102+
- Severity: P2
103+
- Invariant: Codes and machine-readable diagnostics stay documented and
104+
snapshotable.
105+
- Evidence: `test_every_error_code_is_documented()` covers all `ErrorCode`
106+
anchors.
107+
- User Impact: CI and agents can link users to stable remediation docs.
108+
- Required Fix: Keep every new code documented before release.
109+
- Required Proof: Diagnostics contract tests.
110+
- Collateral: `site/content/docs/errors.md`.
111+
- Confidence: High
112+
113+
### Docs Site
114+
115+
- Steward: Documentation Site
116+
- Area: Public diagnostic docs
117+
- Severity: P1
118+
- Invariant: Public docs match current API names, tuple shapes, and render
119+
behavior.
120+
- Evidence: Error-handling docs now describe `to_diagnostic()` and framework
121+
debug-page usage; a docs typo incorrectly referenced `ErrorCode.K_RUN_001`
122+
before this roadmap pass.
123+
- User Impact: Framework authors can copy examples without runtime errors.
124+
- Required Fix: Keep docs examples aligned with actual exception attributes.
125+
- Required Proof: Docs source review and docs build when release collateral is
126+
finalized.
127+
- Collateral: `site/content/docs/usage/error-handling.md`,
128+
`site/content/docs/troubleshooting/undefined-variable.md`.
129+
- Confidence: High
130+
131+
### Tests
132+
133+
- Steward: Test Corpus
134+
- Area: Release evidence
135+
- Severity: P1
136+
- Invariant: User-facing diagnostics need focused assertions and release gates.
137+
- Evidence: Focused diagnostics suite passes locally.
138+
- User Impact: Regressions in escaping, attribution, or stack context fail before
139+
release.
140+
- Required Fix: Run full release-relevant gates before tagging.
141+
- Required Proof: `make lint`, `make ty`, diagnostics tests, full test coverage;
142+
`make verify-stability` for final release candidate.
143+
- Collateral: None beyond test output; no fixtures changed.
144+
- Confidence: High
145+
146+
### Benchmark
147+
148+
- Steward: Benchmark
149+
- Area: Performance evidence
150+
- Severity: P3
151+
- Invariant: Hot-path claims require benchmarks, but source-mapping fixes do not
152+
need new public performance claims.
153+
- Evidence: The current changes do not advertise speedups.
154+
- User Impact: Avoids noisy benchmark churn for a diagnostics release.
155+
- Required Fix: No benchmark update unless a compiler/render hot-path change is
156+
added after this plan.
157+
- Required Proof: Explicit no-benchmark rationale in release notes or PR body.
158+
- Collateral: no collateral: no performance claim or baseline change.
159+
- Confidence: Medium
160+
161+
### GitHub Workflow
162+
163+
- Steward: GitHub Workflow
164+
- Area: Release mechanics
165+
- Severity: P2
166+
- Invariant: Release/publish and floating action tag behavior must not change
167+
casually.
168+
- Evidence: No workflow changes are needed for a diagnostics release.
169+
- User Impact: Existing release automation remains stable.
170+
- Required Fix: Use existing `make verify-stability`, release, and action-tag
171+
process; do not alter workflows.
172+
- Required Proof: Local gate output and CI on the release PR.
173+
- Collateral: no collateral: workflows unchanged.
174+
- Confidence: High
175+
176+
## Convergence
177+
178+
All consulted stewards converge on a narrow 0.10.0: ship diagnostics hardening,
179+
document it, and verify release gates. No steward requires new syntax, public
180+
configuration, schemas, workflow permissions, or dependencies for this release.
181+
182+
## Minority Reports
183+
184+
- Large-app ergonomics remains important, but it should not be bundled into
185+
0.10.0 unless a specific approved implementation is already complete and
186+
covered by docs/tests. It has open questions around API shape and suppression
187+
policy.
188+
- Benchmark steward does not require a new baseline for current diagnostics work,
189+
but would object if later 0.10.0 changes alter compiler or render hot paths
190+
while skipping performance evidence.
191+
192+
## Ranked Backlog
193+
194+
1. Release collateral for diagnostics: update `CHANGELOG.md`, docs examples, and
195+
this roadmap.
196+
2. Verification: run focused diagnostics tests, `make lint`, `make ty`, full
197+
test/coverage gate, safety/concurrency tests, docs build, and package smoke
198+
before tagging.
199+
3. Release notes: maintain `site/content/releases/0.10.0.md` with the final
200+
release date and user-facing upgrade notes.
201+
4. Optional hardening: add `TemplateRuntimeError.to_diagnostic()` only after a
202+
public-contract check-in, because it widens the programmatic surface beyond
203+
the current undefined-error implementation.
204+
5. Post-release: resume `plan/epic-large-app-ergonomics.md` starting with
205+
route-agnostic context/catalog checks that already have evidence.
206+
207+
## Not Now
208+
209+
- No `TemplateDiagnostic` top-level export without explicit public API approval.
210+
- No new CLI flags or `Environment(...)` knobs.
211+
- No privacy-lint suppression/config surface.
212+
- No public render-packet schema.
213+
- No schema or report-template changes.
214+
- No workflow, publish, or action-tag behavior changes.
215+
- No benchmark baseline churn unless later code changes affect hot paths.
216+
217+
## Parity Matrix
218+
219+
| Contract | API/CLI | Programmatic | Protocol | Schema/Types | Docs | Examples | Tests |
220+
|---|---|---|---|---|---|---|---|
221+
| Undefined diagnostics | no CLI change | `UndefinedError.to_diagnostic()` | none | internal dataclasses only | error handling, troubleshooting | no new example | diagnostics contract |
222+
| Source attribution | no CLI change | exception fields/snippets | none | none | troubleshooting | no new example | coalescing, slots, streaming |
223+
| HTML/Markdown renderers | no CLI change | diagnostic format helpers | none | none | error handling | no new example | escaped output assertions |
224+
| Release process | existing Makefile | none | none | none | changelog/release notes | no new example | lint, ty, tests, verify-stability |
225+
226+
## Execution Record
227+
228+
- 2026-05-30: `uv run pytest tests/test_diagnostics_contract.py` passed.
229+
- 2026-05-30: `make lint` passed.
230+
- 2026-05-30: `make ty` passed.
231+
- 2026-05-30: `uv run pytest tests/test_diagnostics_contract.py tests/test_public_api_snapshot.py` passed.
232+
- 2026-05-30: `make docs` initially built 262 pages with one generated autodoc
233+
`/llms.txt` health warning. After release-page and metadata updates, `make
234+
docs` built 270 pages with clean health output.
235+
- 2026-05-30: `make test-cov` passed: 4,279 passed, 5 skipped, 84.14% coverage against the 83% floor.
236+
- 2026-05-30: `make format-check` passed.
237+
- 2026-05-30: `make package-smoke` passed against the prepared `0.10.0` package metadata.
238+
- 2026-05-30: `make test-safety` passed under `PYTHON_GIL=0`: 131 passed.
239+
- 2026-05-30: Version metadata updated to `0.10.0` in `pyproject.toml` and
240+
`uv.lock`.
241+
- 2026-05-30: `site/content/releases/0.10.0.md` added.
242+
- 2026-05-30: Focused release verification passed against 0.10.0 metadata:
243+
diagnostics contract, public API snapshot, compiler AST baseline, and async
244+
streaming exception contract.
245+
- 2026-05-30: Final `make test-cov` passed: 4,279 passed, 5 skipped, 84.13%
246+
coverage against the 83% floor.
247+
- 2026-05-30: Final `make verify-stability` passed: lint, format-check, ty,
248+
full coverage, safety, and package smoke all completed successfully against
249+
the prepared `0.10.0` release candidate.
250+
- 2026-05-30: README and installation docs updated for `0.10.0` upgrade/version
251+
collateral; `make docs` rebuilt the site successfully with clean health checks.
252+
- 2026-05-30: After fetching, remote `main` was at `66cf8ec` and the local
253+
pre-squash history diverged. Release prep was replayed onto
254+
`codex/release-0.10.0` from current `origin/main` to avoid publishing the
255+
duplicate pre-squash history. Remote tag push, GitHub release, PyPI publish,
256+
and floating action tag update remain pending.
257+
- 2026-05-30: Origin-main-based focused verification passed:
258+
`uv run pytest tests/test_diagnostics_contract.py tests/test_public_api_snapshot.py tests/test_kida_async_rendering.py::TestAsyncExceptionPropagation::test_error_in_async_iterable_propagates`
259+
reported 15 passed.
260+
- 2026-05-30: Origin-main-based docs verification passed: `make docs` found no
261+
pending site changes and completed with clean health checks.
262+
- 2026-05-30: Origin-main-based final `make verify-stability` passed: lint,
263+
format-check, ty, full coverage, safety, and package smoke completed
264+
successfully. Coverage summary: 84.1% against the 83% floor.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "kida-templates"
7-
version = "0.9.0"
7+
version = "0.10.0"
88
description = "Pure-Python template components with static validation for HTML, Markdown, terminal, and CI reports"
99
readme = "README.md"
1010
requires-python = ">=3.14"

site/content/docs/get-started/installation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ uv sync
6767

6868
```python
6969
import kida
70-
print(kida.__version__) # 0.9.0
70+
print(kida.__version__) # 0.10.0
7171
```
7272

7373
Or from the command line:

site/content/docs/usage/error-handling.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ When an error occurs inside a `{% def %}` component, `TemplateRuntimeError` and
148148
try:
149149
template.render(data=data)
150150
except TemplateRuntimeError as e:
151-
for def_name, lineno, tpl_name in e.component_stack:
151+
for tpl_name, lineno, def_name in e.component_stack:
152152
print(f" in {def_name}() at {tpl_name}:{lineno}")
153153
```
154154

@@ -230,7 +230,7 @@ from kida import UndefinedError, ErrorCode
230230
try:
231231
template.render()
232232
except UndefinedError as e:
233-
print(e.code) # ErrorCode.K_RUN_001
233+
print(e.code) # ErrorCode.UNDEFINED_VARIABLE
234234
print(e.code.value) # "K-RUN-001"
235235
```
236236

site/content/releases/0.10.0.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
title: Kida 0.10.0
3+
description: Structured diagnostics, source attribution hardening, and release-readiness cleanup
4+
date: 2026-05-30
5+
draft: false
6+
lang: en
7+
tags: [release, changelog, diagnostics, errors, framework-integration, streaming]
8+
keywords: [release, 0.10.0, diagnostics, UndefinedError, source attribution, streaming, framework debug views]
9+
---
10+
11+
# v0.10.0
12+
13+
**Released** 2026-05-30.
14+
15+
Kida 0.10.0 is a focused diagnostics release. It gives framework debug pages a
16+
structured error payload for undefined values, tightens source attribution across
17+
optimized and streaming render paths, and keeps the broader large-app roadmap out
18+
of this release until its public contracts are ready.
19+
20+
## Added
21+
22+
- **Structured undefined diagnostics**`UndefinedError.to_diagnostic()` returns
23+
a surface-neutral payload with code, kind, location, source snippet, ordered
24+
hints, docs URL, metadata, template stack, and component stack.
25+
- **HTML and Markdown diagnostic renderers** — The diagnostic payload can render
26+
escaped HTML fragments/pages or GitHub-flavored Markdown without downstream
27+
frameworks parsing terminal-formatted exception strings.
28+
29+
## Fixed
30+
31+
- **Optimized templates keep source locations** — F-string coalescing preserves
32+
the template line marker used by undefined diagnostics, so optimized output
33+
still points at the source line users can edit.
34+
- **Imported component slot failures point at caller source** — Errors raised
35+
inside slot bodies passed to imported components now report the caller template
36+
as the primary diagnostic location while retaining component-stack context.
37+
- **Streaming runtime errors match full render diagnostics** — Generic Python
38+
exceptions raised during streaming are wrapped with template name and line
39+
information consistently with full render.
40+
41+
## Upgrade Notes
42+
43+
1. Framework debug pages should prefer `UndefinedError.to_diagnostic()` over
44+
parsing `str(exc)` or `format_compact()`.
45+
2. If a test expected raw exceptions from async streaming, update it to assert
46+
`TemplateRuntimeError` and inspect `__cause__` for the original exception.
47+
3. If you maintain compiler AST snapshots, regenerate them for the coalescing
48+
line-marker contract.
49+
50+
## Why this change
51+
52+
Kida's diagnostic strings are optimized for terminal output. Frameworks need the
53+
same facts as plain data so they can render their own debug UI safely. This
54+
release makes undefined errors inspectable without scraping styled terminal
55+
text, and it closes a few attribution gaps that made optimized or streaming
56+
renders harder to debug than full renders.

0 commit comments

Comments
 (0)