Files
weatherreporter/docs/internal/generatedtext.md

3.7 KiB

Generated Text Internals

This document describes structured generated-text handling in internal/generatedtext.

Purpose

internal/generatedtext validates structured text returned for generated-text-template reports and builds curated render contexts for templates. It also owns the generated-text catalog that connects report definitions to validators, render-context builders, schema assets, and template assets. The implemented contracts are Tomorrow Report and Hourly Report.

Inputs And Outputs

Inputs:

  • raw GeneratedText JSON for Tomorrow Report or Hourly Report
  • report metadata from internal/briefing
  • a module snapshot from internal/module
  • validated generated text

Outputs:

  • typed Tomorrow generated text
  • typed Hourly generated text
  • normalized stable JSON for validated generated text
  • typed TomorrowRenderContext values for internal/reporttemplate
  • typed HourlyRenderContext values for internal/reporttemplate
  • generated-text catalog handlers for report definitions that use generated_text_template

The hourly generated text JSON accepts:

{
  "summary": "string",
  "forecast_discussion": "string",
  "precipitation_timing": "string",
  "confidence": "string"
}

summary and forecast_discussion are required after trimming whitespace. precipitation_timing and confidence are optional and omitted from normalized JSON when blank.

The Tomorrow generated text JSON accepts:

{
  "summary": "string",
  "forecast_discussion": ["string"],
  "precipitation_timing": "string",
  "confidence": "string"
}

summary is required after trimming whitespace. forecast_discussion must contain at least one nonblank paragraph after trimming blank items. precipitation_timing and confidence are optional and omitted from normalized JSON when blank.

Boundaries

  • This package owns typed generated-text validation and render-context shaping.
  • It owns generated-text catalog lookup for schema/template combinations.
  • It uses typed module snapshot decoding through module.StanzaValue.
  • It does not invoke Scriptorium, write state artifacts, choose report definitions, compare snapshots, or own embedded template/schema files.
  • It renders through internal/reporttemplate; embedded asset lookup remains in internal/reporttemplate.
  • It does not use a Go JSON Schema dependency; schema enforcement in Go is limited to typed JSON decoding, unknown-field rejection, and required-field checks.

Failure Behavior

  • Malformed generated-text JSON fails with decode context.
  • Unknown generated-text JSON fields fail during decoding.
  • Empty required fields fail after trimming whitespace.
  • Tomorrow forecast discussion fails when no nonblank paragraphs remain.
  • Missing optional render-context stanzas become nil module pointers.
  • Invalid render metadata, including missing timezone, missing generated time, or invalid valid period, fails before template rendering.
  • Unsupported generated-text schema IDs, template IDs, or schema/template combinations fail during catalog lookup with report ID context.

Tests

Inspect:

  • internal/generatedtext/hourly_test.go
  • internal/generatedtext/tomorrow_test.go
  • internal/generatedtext/catalog_test.go
  • internal/generatedtext/render_context_test.go

Invariants

  • Render contexts are curated structs, not raw prompt-input packages.
  • Required generated text is normalized before downstream artifact storage.
  • Generated-text-template reports must have one catalog entry matching their report definition schema and template IDs.
  • Missing optional weather narrative stanzas produce empty or fallback render context fields rather than forcing raw module data into templates.