Refresh deterministic domain documentation
This commit is contained in:
@@ -1,94 +1,67 @@
|
||||
# Fact Contracts Internals
|
||||
|
||||
This document describes the fact contract boundary.
|
||||
`internal/facts` is the deterministic boundary between a collected weather
|
||||
bundle and report-scoped facts. It preserves normalized source values and then
|
||||
selects and summarizes the values needed for one resolved report. Provider
|
||||
transport and normalized bundle semantics belong to
|
||||
[weather-data internals](weather-data.md); report identity and valid-period
|
||||
selection belong to [report registry internals](report-registry.md).
|
||||
|
||||
## Purpose
|
||||
## Collected facts
|
||||
|
||||
`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.
|
||||
`BuildCollected` projects a `weatherdata.Bundle` into `CollectedFacts`. It
|
||||
retains the fetched timestamp and every normalized product: observations,
|
||||
current conditions, hourly, narrative, alerts, discussion, daily, weather
|
||||
story, and convective outlook data. Source provenance and warnings are copied
|
||||
into their own slices so downstream consumers can inspect data completeness
|
||||
without treating it as an ordinary weather fact.
|
||||
|
||||
## Inputs And Outputs
|
||||
A nil bundle produces an empty collected value. Collection itself, missing
|
||||
source policy, and source hashes are outside this package.
|
||||
|
||||
Inputs:
|
||||
## Report-scoped derivation
|
||||
|
||||
- `weatherdata.Bundle` from the Weather API adapter
|
||||
- resolved report definition and valid period
|
||||
- report timezone
|
||||
- configured daypart definitions
|
||||
`BuildDerived` requires a valid resolved period and a valid report timezone. It
|
||||
uses half-open period overlap to select hourly, narrative, daily, and alert
|
||||
data; it also derives precipitation timing. Convective outlooks are retained
|
||||
only when their valid interval overlaps the report period, with discussions
|
||||
kept for represented outlook days. Both collections are sorted deterministically.
|
||||
|
||||
Outputs:
|
||||
Report identity controls the summary shape:
|
||||
|
||||
- `facts.CollectedFacts` with normalized source facts plus separate source
|
||||
provenance and warnings. SPC convective outlook source data is carried
|
||||
through when present in the bundle, including upstream geometry and source
|
||||
provenance.
|
||||
- `facts.DerivedFacts` with valid-period forecast slices, alert overlaps,
|
||||
report-period SPC convective outlooks and discussions, daily summaries,
|
||||
daypart summaries, and Storm Report window summary
|
||||
| Report family | Derived summary |
|
||||
| --- | --- |
|
||||
| Hourly | Rolling-period selections and precipitation timing; no daily or daypart summary |
|
||||
| Daily, Today, Tomorrow | One local civil-day summary and its dayparts |
|
||||
| Three-day, Weekend | One clipped daily summary for each overlapping local day |
|
||||
| Storm | One summary for the explicit report window |
|
||||
|
||||
Hourly Report uses the generic valid-period hourly and narrative selection
|
||||
for its rolling six-hour window. Its derived facts include precipitation timing
|
||||
from the selected hourly periods, alert overlaps for the six-hour period, and
|
||||
SPC outlooks/discussions overlapping that period. It does not build daily
|
||||
summaries, daypart summaries, or a storm-window summary.
|
||||
`DaypartSummaries` is collected from the resulting daily or storm summaries.
|
||||
The detailed grouping, daypart-window, and alert rules are owned by
|
||||
[forecast derivation](forecast-derivation.md).
|
||||
|
||||
## Boundaries
|
||||
## Missing data and failures
|
||||
|
||||
- This package owns fact assembly and reusable deterministic derivation for a
|
||||
report run.
|
||||
- SPC convective outlook derivation selects already-collected outlooks whose
|
||||
half-open valid intervals overlap the resolved report period and retains
|
||||
discussions for represented outlook days.
|
||||
- Derived SPC outlook records preserve the collected outlook fields, including
|
||||
geometry, for downstream components that need source-level facts. Prompt
|
||||
modules decide which fields are exposed to Scriptorium.
|
||||
- It does not fetch upstream data, build prompt wording, compare prior
|
||||
snapshots, write workflow state, invoke Scriptorium, or define modules.
|
||||
Optional normalized products remain nil or yield empty selections; the package
|
||||
does not create substitute values. A present convective-outlook run with no
|
||||
matching outlooks produces non-nil empty outlook and discussion slices, while
|
||||
a missing run produces nil slices.
|
||||
|
||||
## Config Fields Used
|
||||
Derivation fails for an invalid report period, invalid timezone, unsupported
|
||||
report ID, or when a requested daily summary has no hourly forecast data.
|
||||
Invalid daypart definitions surface from forecast derivation. The package does
|
||||
not access the CLI, filesystem, subprocesses, or network.
|
||||
|
||||
- `dayparts[].name`
|
||||
- `dayparts[].start`
|
||||
- `dayparts[].end`
|
||||
- `weather_api.timezone`
|
||||
## Verification and invariants
|
||||
|
||||
## External Adapters Used
|
||||
Focused tests cover collected-fact separation, report-period selection,
|
||||
hourly and storm behavior, daily and partial-day summaries, and convective
|
||||
outlook selection:
|
||||
|
||||
None directly. Collected facts are built from `weatherdata.Bundle`.
|
||||
```sh
|
||||
go test ./internal/facts
|
||||
```
|
||||
|
||||
## 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.
|
||||
- Hourly Report can derive its default module facts without daily or
|
||||
daypart summaries.
|
||||
- Missing optional narrative, alert, discussion, daily, or weather story data
|
||||
produces empty or nil derived fields.
|
||||
- Missing optional SPC convective outlook data produces a nil collected field.
|
||||
- A present SPC convective outlook source with no report-period matches
|
||||
produces non-nil empty derived outlook and discussion slices.
|
||||
|
||||
## Tests
|
||||
|
||||
Inspect:
|
||||
|
||||
- `internal/facts/facts_test.go`
|
||||
- `internal/app/app_test.go`
|
||||
|
||||
## Invariants
|
||||
|
||||
- Collected facts are built once from a fetched bundle.
|
||||
- Derived facts are scoped to one resolved report.
|
||||
- SPC convective outlook selection uses the resolved report period and the
|
||||
already-collected outlook run.
|
||||
- Source provenance and warnings stay separate from ordinary fact fields.
|
||||
- Prompt-specific wording and one-off presentation decisions stay outside this
|
||||
package.
|
||||
Facts are derived once for a resolved report from already collected data.
|
||||
They remain reusable structured values: prompt wording, state persistence,
|
||||
prior-report comparison, and template presentation are owned elsewhere.
|
||||
|
||||
Reference in New Issue
Block a user