2.0 KiB
2.0 KiB
Fact Contracts Internals
This document describes the fact contract boundary.
Purpose
internal/facts separates normalized upstream facts collected for a report run
from conservative report-scoped facts derived from them. The package gives app
orchestration one place to build reusable facts before module execution.
Inputs And Outputs
Inputs:
weatherdata.Bundlefrom the Weather API adapter- resolved report definition and valid period
- report timezone
- configured daypart definitions
Outputs:
facts.CollectedFactswith normalized source facts plus separate source provenance and warningsfacts.DerivedFactswith valid-period forecast slices, alert overlaps, daily summaries, daypart summaries, and Storm Report window summary
Boundaries
- This package owns fact assembly and reusable deterministic derivation for a report run.
- It does not fetch upstream data, build prompt wording, compare prior snapshots, write workflow state, invoke Scriptorium, or define modules.
Config Fields Used
dayparts[].namedayparts[].startdayparts[].endweather_api.timezone
External Adapters Used
None directly. Collected facts are built from weatherdata.Bundle.
State Or Manifest Behavior
None. Source provenance and warnings remain data fields for downstream metadata and inspection.
Failure Behavior
- Invalid or missing report valid periods return an error.
- Invalid timezone names return an error.
- Missing required hourly forecast data returns the underlying forecast derivation error for reports that require daily summaries.
- Missing optional narrative, alert, discussion, daily, or weather story data produces empty or nil derived fields.
Tests
Inspect:
internal/facts/facts_test.gointernal/app/app_test.go
Invariants
- Collected facts are built once from a fetched bundle.
- Derived facts are scoped to one resolved report.
- Source provenance and warnings stay separate from ordinary fact fields.
- Prompt-specific wording and one-off presentation decisions stay outside this package.