Files
weatherreporter/docs/internal/briefing.md

4.9 KiB

Module Builder Internals

internal/briefing builds typed module outputs from resolved report context, collected facts, and derived facts. It owns the module registry, including module support, fact requirements, option types, missing-data policy, builders, and prompt-export hooks. It does not collect data, derive periods, write a snapshot, construct YAML, invoke Promptkit, or render a report.

Registry and construction

Every ModuleDefinition declares an ID, stanza name, default option value, required collected and derived facts, supported report IDs, missing-data behavior, duplicate policy, builder, and optional prompt exporter.

BuildModule first verifies the requested module, report compatibility, and option shape. It then applies the declared missing-data behavior:

  • omit returns no output for unavailable optional facts;
  • error returns the missing fact requirements; and
  • empty allows the builder to emit an explicit checked-empty value.

Unsupported warn behavior, missing builders, duplicate registry IDs or stanza names, output ID or stanza mismatches, and exporter failures all return errors with module context. A successful builder gets a pass-through prompt value unless its definition supplies an exporter.

Built value families

Source-oriented builders shape report metadata, current conditions, narrative and hourly forecasts, alert digest, SPC outlooks and discussion, area forecast discussion, and weather story. Derived builders shape daily and daypart summaries, precipitation timing, outdoor windows, and the report-specific Daily, Today, and Tomorrow planning values.

The daily summary preserves generic feels-like values as apparent_temperature_max_f; it does not label them as a heat index. Daypart temperature phrases retain below-zero meaning, including through temperature trends that cross zero. Outdoor windows add a 25-point risk penalty and an explicit reason for each snow, ice, or fog indicator. Equal scores retain input order for both best and worst windows.

The module registry preserves rich values for templates and snapshots while curating prompt exports where needed. In particular, source warnings are a metadata summary, checked-empty alerts and SPC outlooks remain distinct from missing sources, and prompt-safe SPC values omit geometry and other template-only or source details. The complete module composition is in module internals; fact derivation is in fact contracts.

Derived daypart-summary maps use the forecast package's canonical daypart identity and reject any collision instead of replacing an earlier value. Planning applies the same identity when recognizing morning, afternoon, evening, and overnight windows; display labels remain separate and preserve configured text with rune-safe first-letter capitalization.

The embedded SPC background-definition asset records its authoritative sources, source update dates, and maintainer review schedule. Its categorical official_description values transcribe the SPC convective-outlook risk table; its Conditional Intensity Group entries follow the SPC conditional-intensity reference. plain_language values are Weatherreporter summaries. Weatherreporter maintainers review the asset annually and whenever either source changes.

area_forecast_discussion accepts an optional typed section filter. Accepted typed option pointers are normalized to the declared value type before builder execution. Planning modules are report-specific: daily_planning supports Daily, today_planning supports Today, and tomorrow_planning supports Tomorrow.

Missing data and boundaries

Optional current conditions, narrative products, discussions, and weather stories may be omitted. A weather story is usable only when it has non-blank displayable content (title, description, alternate text, or download URL) or a valid start/end period; otherwise collection applies its optional-source policy and the module is omitted. Required derived modules fail when their declared facts are unavailable. Empty alert and outlook runs can still produce checked-empty modules. SPC discussion is omitted unless a retained categorical outlook meets the package's severity criterion and matching discussion text exists.

Effective units, timezone, and location context arrive in ModuleContext from configuration and resolved report metadata. Field defaults are owned by configuration, and prompt-package layout is owned by prompt input.

Verification and invariants

Focused tests cover source and derived values, registry validation, option handling, prompt exporters, support rules, and missing-data behavior:

go test ./internal/briefing

Builders emit structured facts, never report prose. The app collects their outputs into an in-memory module snapshot for prompt input and rendering.