Files
weatherreporter/docs/internal/generatedtext.md

4.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 Daily render context, Today Report, Tomorrow Report, and Hourly Report.

Inputs And Outputs

Inputs:

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

Outputs:

  • typed Daily generated text
  • typed Today generated text
  • typed Tomorrow generated text
  • typed Hourly generated text
  • normalized stable JSON for validated generated text
  • typed DailyRenderContext values for internal/reporttemplate
  • typed TodayRenderContext values for internal/reporttemplate
  • 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 Daily generated text JSON accepts the same public fields and validation rules as Tomorrow. Its catalog entry is selected through schema ID daily and template ID daily, with prompt ID weather.daily_generated_text.

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

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 Today generated text JSON accepts the same public fields and validation rules as Tomorrow. It is selected by the active Today report definition through schema ID today, template ID today, and prompt ID weather.today_generated_text:

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

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.
  • Daily, Today, and 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/daily_test.go
  • internal/generatedtext/today_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.