Skip to content

feat: RenderCapture — block-level capture, search indexing, freeze cache#99

Merged
lbliii merged 5 commits intomainfrom
lbliii/fragment-streaming
Apr 15, 2026
Merged

feat: RenderCapture — block-level capture, search indexing, freeze cache#99
lbliii merged 5 commits intomainfrom
lbliii/fragment-streaming

Conversation

@lbliii
Copy link
Copy Markdown
Owner

@lbliii lbliii commented Apr 15, 2026

Summary

  • RenderCapture: Opt-in block-level content capture during template.render(), using the same ContextVar + compile-time flag pattern as profiling. Zero overhead when disabled (enable_capture=False elides all capture AST).
  • Fragment identity: Each captured block gets content_hash (SHA256[:16]), role, depends_on, and cache_scope bridged from BlockMetadata at render time.
  • RenderManifest + SearchManifestBuilder: Batch accumulation across a freeze, with auto-derived search indexing. FieldExtractor protocol enables framework-agnostic field mapping; default extractor reads raw context (doc.body) instead of stripping rendered HTML.
  • FreezeCache: Auto-caches site-scoped blocks (no context dependencies) during batch renders. Content-hash guard prevents serving stale content if cache_scope classification is wrong.
  • CLI: kida manifest renders templates with capture and outputs JSON; kida diff computes semantic block-level diffs between manifests.

Test plan

  • 35 tests for RenderCapture (unit, integration, profiling co-existence, metadata bridging)
  • 35 tests for RenderManifest (accumulation, diffing, search builder, raw context extraction, FreezeCache unit + integration)
  • Full suite: 3852 passed, 0 regressions
  • Verify ty check on changed files only (109 pre-existing diagnostics in compiler/expressions.py cause full-src hook to fail)

🤖 Generated with Claude Code

lbliii and others added 5 commits April 15, 2026 10:56
…ering

Introduces a new render-time data capture system parallel to the existing
RenderAccumulator (profiling). Templates compiled with enable_capture=True
inject capture hooks at block call sites. When a captured_render() context
manager is active, block content, content hashes, context snapshots, and
template names are recorded into a RenderCapture object.

- New module: kida/render_capture.py (Fragment, RenderCapture, captured_render)
- New Environment flag: enable_capture (default False, zero overhead when off)
- Compiler: include_cap parameter in preamble, capture hooks at block call sites
- Template: context snapshot + template_name in _render_scaffold
- 28 new tests covering unit, integration, profiling co-existence, and edge cases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…fing

Bridges BlockMetadata (role, depends_on) into captured Fragments at
render time. The _render_scaffold populates block metadata from
template analysis, so captured blocks carry semantic roles (content,
navigation, etc.) and dependency information automatically.

- RenderCapture._record() now pulls role/depends_on from BlockMetadata
- _render_scaffold bridges block_metadata() into active capture
- RenderCapture.changed_from() enables semantic block-level diffing
- 7 new tests for metadata bridging and diffing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces RenderManifest for accumulating captures across batch renders
(e.g., static site freeze), SearchManifestBuilder for auto-deriving
search indexes from block roles, and ManifestDiff for semantic
deploy-level diffing.

- RenderManifest: batch accumulation, all_fragments(), unique_content_hashes()
- SearchManifestBuilder: auto-classifies blocks by role, extracts facets
  from context, produces Chirp-compatible search manifest format
- ManifestDiff: added/removed/changed URLs with block-level granularity
- 14 new tests covering manifest ops, diffing, and search generation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- `kida manifest <dir>` renders templates and outputs a capture manifest
  as JSON with block roles, content hashes, and dependency metadata.
  Supports --data for context injection and --search for auto-derived
  search index output.
- `kida diff <old> <new>` computes semantic diff between two manifests,
  reporting added/removed/changed URLs with block-level granularity.
  Exit code 1 when changes detected, 0 when identical.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SearchManifestBuilder now uses raw context values (doc.body) instead of
rendered HTML for search indexing, with a FieldExtractor protocol for
framework-agnostic field mapping. FreezeCache auto-caches site-scoped
blocks during batch renders, targeting the 59% redundant render opportunity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lbliii lbliii merged commit c587782 into main Apr 15, 2026
10 checks passed
@lbliii lbliii deleted the lbliii/fragment-streaming branch April 15, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant