Reconcile internal implementation guides
This commit is contained in:
@@ -1,59 +1,36 @@
|
||||
# Collection Internals
|
||||
|
||||
`internal/collect` is the application-facing boundary for collecting the
|
||||
`internal/collect` is the small application-facing boundary that obtains one
|
||||
normalized Weather API bundle. The external HTTP contract belongs in the
|
||||
[Weather API integration guide](../integrations/weatherapi.md); normalized data
|
||||
semantics belong in [weather-data internals](weather-data.md).
|
||||
[Weather API integration guide](../integrations/weatherapi.md); normalized
|
||||
source values belong in [weather-data internals](weather-data.md).
|
||||
|
||||
## Contract
|
||||
|
||||
`Run` accepts a `context.Context` and a `Request` containing effective
|
||||
`config.Config`. It constructs the Weather API adapter from that configuration,
|
||||
calls `FetchBundle`, and returns `Result{Bundle: *weatherdata.Bundle}`.
|
||||
`Run` receives a context and effective configuration in `Request`. It creates
|
||||
the Weather API adapter, calls `FetchBundle`, and returns the adapter's
|
||||
normalized bundle in `Result`. Adapter construction errors are wrapped as
|
||||
weather-collection setup errors and fetch errors as bundle-collection errors.
|
||||
|
||||
The adapter's successful readiness request for current conditions is reused as
|
||||
that normalized source; collection does not trigger a second identical current
|
||||
conditions request.
|
||||
The package neither chooses reports nor derives facts, builds modules, invokes
|
||||
Promptkit, writes files, or sends notifications. Request scheduling, endpoint
|
||||
retrieval, response limits, and source-level warnings belong to the Weather
|
||||
API adapter and its integration contract.
|
||||
|
||||
After readiness succeeds, the adapter obtains the other independent source
|
||||
responses concurrently. It merges their normalized results in the established
|
||||
source order, so provenance, warnings, and source-local failures remain
|
||||
deterministic. Cancellation remains authoritative for every in-flight request.
|
||||
## Application Use
|
||||
|
||||
The package wraps adapter construction failures, including an invalid Weather
|
||||
API base URL, as weather-collection setup errors and fetch failures as
|
||||
bundle-collection errors. It does not retry, persist, select reports, derive
|
||||
facts, build modules, invoke Promptkit, or notify Distributor.
|
||||
`internal/app` owns the `Collector` interface used by report workflows and
|
||||
tests. Its default implementation delegates to `collect.Run`; callers may
|
||||
substitute a collector at that boundary. Application orchestration owns
|
||||
collection timing, reuse across a workflow, and the handling of nil collection
|
||||
results. See [app orchestration internals](app-orchestration.md) for that
|
||||
flow.
|
||||
|
||||
Fetch failures retain Weather API endpoint context but do not project upstream
|
||||
response bodies into application-facing errors. Oversized response bodies fail
|
||||
collection before source decoding.
|
||||
## Verification
|
||||
|
||||
The required hourly product must contain one or more periods with usable time
|
||||
bounds. An invalid hourly product fails collection before derivation begins.
|
||||
Focused package tests cover a successful fetch and wrapping failures from
|
||||
adapter construction and bundle retrieval:
|
||||
|
||||
## Application Composition
|
||||
|
||||
`internal/app` owns the narrow `Collector` interface used by workflow tests;
|
||||
the production implementation delegates to `collect.Run`. Generation, batch
|
||||
execution, and explicit bundle fetching all use this boundary. Application
|
||||
orchestration rejects a nil collector result or a nil bundle before report work
|
||||
can continue.
|
||||
|
||||
Single-report generation and a batch each collect once. A batch passes the same
|
||||
normalized collection to planning and to every report it generates. Collection
|
||||
failure prevents later workflow work for that request.
|
||||
|
||||
## Boundaries And Invariants
|
||||
|
||||
Collection owns adapter creation and retrieval of one normalized bundle. It
|
||||
must not make report, period, batch, prompt, module, filesystem, or notification
|
||||
decisions.
|
||||
|
||||
- App-facing Weather API collection always passes through this package.
|
||||
- The returned value is normalized source data, not facts or prompt input.
|
||||
- Context cancellation is passed to the Weather API adapter.
|
||||
- Errors retain whether setup or fetching failed.
|
||||
|
||||
Focused tests are in `internal/collect/collect_test.go`; orchestration use is
|
||||
also covered by `internal/app/app_test.go`.
|
||||
```sh
|
||||
go test ./internal/collect
|
||||
```
|
||||
|
||||
@@ -2,74 +2,46 @@
|
||||
|
||||
`internal/forecast` deterministically selects and summarizes normalized
|
||||
forecast data. It has no transport, filesystem, CLI, subprocess, or report
|
||||
registry dependency. Its summaries are consumed by
|
||||
[fact contracts](facts.md) and later module builders.
|
||||
registry dependency. The report-scoped caller is [fact
|
||||
contracts](facts.md), which owns the choice of data required by each report.
|
||||
|
||||
## Period and daypart semantics
|
||||
## Daily Derivation
|
||||
|
||||
Selections use `timeutil.Period` half-open overlap: a value is selected only
|
||||
when both intervals share time. `BuildDailySummary` creates one local civil
|
||||
day; `BuildPeriodDailySummaries` intersects every local civil day with the
|
||||
requested period, preserving partial first and last days.
|
||||
`BuildDailySummary` builds one summary for one local civil day. The facts
|
||||
layer calls it for Daily, Today, and Tomorrow reports; it does not provide a
|
||||
multi-day or arbitrary-period summary constructor. `timeutil.Period` supplies
|
||||
the shared half-open overlap rule used while selecting source values.
|
||||
|
||||
`ResolveDayparts` converts each configured name, start clock, and end clock
|
||||
into a local window. An end clock at or before its start clock wraps into the
|
||||
next civil day. The daypart and timezone defaults are defined in the
|
||||
[configuration reference](../config.md), not here.
|
||||
`ResolveDayparts` turns configured local clock ranges into windows. A range
|
||||
whose end is not after its start continues into the next civil day. The
|
||||
available daypart and timezone settings are defined in the
|
||||
[configuration reference](../config.md).
|
||||
|
||||
## Deterministic summaries
|
||||
The summary keeps selected hourly and narrative values, the discussion,
|
||||
source warnings and provenance, alert overlaps, and one summary for each
|
||||
resolved daypart. Daypart summaries derive their measurements, conditions,
|
||||
weather indicators, and precipitation timing from normalized forecast
|
||||
periods. `BuildPrecipTiming` is also available to the facts layer for a
|
||||
report's selected hourly periods.
|
||||
|
||||
`BuildDailySummary` requires an hourly run with at least one period. It adds
|
||||
the selected narrative periods, discussion, alert overlaps, source provenance,
|
||||
source warnings, and one `DaypartSummary` per resolved window. A daypart keeps
|
||||
its selected hourly periods and derives temperature and apparent-temperature
|
||||
ranges, timed precipitation and wind maxima, dominant and notable conditions,
|
||||
and weather indicators.
|
||||
## Boundaries And Failures
|
||||
|
||||
Hourly precipitation probabilities must be finite percentages from 0 through
|
||||
100. Daily-summary construction rejects invalid values before they can affect
|
||||
timed maxima or precipitation windows.
|
||||
Daily-summary construction requires a bundle with hourly forecast data,
|
||||
valid precipitation probabilities, and valid daypart definitions. Optional
|
||||
normalized products remain absent when unavailable. Invalid alerts are ignored
|
||||
while valid overlaps are selected for the relevant day or daypart window.
|
||||
|
||||
Indicators are deterministic checks over normalized values and condition text:
|
||||
heat, cold, and wind use package-owned numeric cutoffs; snow, ice, fog, and
|
||||
wind text are detected from the forecast description. `BuildPrecipTiming`
|
||||
sorts periods, records the maximum and first precipitation, groups contiguous
|
||||
periods at or above its package-owned probability threshold, and records
|
||||
thunder mentions.
|
||||
Ice detection uses the bounded condition vocabulary `ice`, `icy`, `freezing`,
|
||||
and `sleet` as whole words.
|
||||
Thresholds, text classification, unit normalization, and alert selection are
|
||||
package implementation rules. Report identity, period selection, and the
|
||||
resulting derived-fact shape are owned by [fact contracts](facts.md); external
|
||||
source semantics are owned by [weather-data internals](weather-data.md).
|
||||
|
||||
Daypart temperature and apparent-temperature ranges are Fahrenheit values, and
|
||||
timed wind maxima are mph values. When only metric source fields are present,
|
||||
they are converted to those units before they are stored or evaluated against
|
||||
indicator thresholds; populated US-customary fields take precedence.
|
||||
## Verification
|
||||
|
||||
Alert overlap parsing supports the normalized alert payload's available timing
|
||||
fields. Unparseable alerts and invalid intervals are ignored; valid overlaps
|
||||
are clipped to the requested period and ordered by alert start time.
|
||||
`DailySummary.AlertOverlaps` is limited to the local civil day, while each
|
||||
daypart evaluates the full alert run against its complete window, including the
|
||||
next-day portion of an overnight window.
|
||||
|
||||
## Missing data and failures
|
||||
|
||||
Empty selections yield empty summary fields rather than generated prose.
|
||||
Direct daily or period-summary calls fail when their required bundle, valid
|
||||
period, hourly data, or daypart definitions are invalid. A nil location uses
|
||||
UTC when these APIs are called directly. Optional narrative, discussion, and
|
||||
alerts remain absent when their normalized products are absent.
|
||||
|
||||
Forecast thresholds used for brief indicators and precipitation timing are
|
||||
implementation rules.
|
||||
|
||||
## Verification and invariants
|
||||
|
||||
Focused tests cover local civil days, clipped periods, daypart resolution,
|
||||
summary metrics, precipitation-window threshold behavior, and alert overlap:
|
||||
Focused `internal/forecast` tests exercise daily and overnight dayparts,
|
||||
summary derivation, invalid precipitation data, precipitation timing, and
|
||||
alert overlap handling. `internal/facts` tests cover the report-scoped caller:
|
||||
|
||||
```sh
|
||||
go test ./internal/forecast ./internal/timeutil
|
||||
go test ./internal/forecast ./internal/facts
|
||||
```
|
||||
|
||||
The package preserves normalized inputs as inspectable structured values and
|
||||
never decides report identity, delivery, or presentation wording.
|
||||
|
||||
@@ -1,27 +1,35 @@
|
||||
# Prompt Input Internals
|
||||
|
||||
`internal/promptinput` converts report metadata, an ordered module snapshot, and source warnings into the YAML `data_package` supplied inline to Promptkit. It owns the package schema, grouping, serialization, and validation; it does not choose an output destination, collect weather, execute a provider, or retain packages after a command ends.
|
||||
`internal/promptinput` turns prepared report metadata and an ordered module
|
||||
snapshot into the YAML data package passed to Promptkit. The externally visible
|
||||
prompt and inline-input contract is owned by the [Promptkit integration
|
||||
guide](../integrations/promptkit.md); preparation of the inputs is owned by
|
||||
[prepared report internals](prepared-report.md).
|
||||
|
||||
## Package Construction
|
||||
|
||||
`Build` produces `weatherreporter.data_package.v4`. Its metadata projection comes from the prepared report identity and copies the run ID; report ID, variant, prompt ID, generation time, timezone, local current date, and valid period; ordered briefing stanzas; and prompt-safe source-warning summaries. Warning summaries include only source, code, severity, message, and completeness impact; raw transport and provenance fields such as endpoints never cross into the provider input. Prompt input contains no historical comparison section.
|
||||
`Build` projects report identity, the report-local current date, source-warning
|
||||
summaries, and each snapshot output's prompt-facing value into a package. It
|
||||
does not expose source transport or provenance details. The module snapshot
|
||||
defines stanza order and selects curated prompt values; the corresponding
|
||||
module contracts are documented in [module internals](module.md) and [briefing
|
||||
internals](briefing.md).
|
||||
|
||||
Briefing is a flat ordered set of stanza values. `Build` uses each output's `DataPackageValue`, so curated prompt exports take precedence and rich values are used only as a fallback. Prompt exports are selected by the [briefing registry](briefing.md), while the rich-versus-prompt contract is in [module internals](module.md).
|
||||
`MarshalYAML` validates the package before serializing it. Serialization emits
|
||||
the metadata stanza first, then groups the remaining recognized stanzas in the
|
||||
package's fixed category order while preserving snapshot order within a
|
||||
category. `Validate` enforces the supported schema version, required report
|
||||
identity and period values, and a nonempty, complete ordered briefing.
|
||||
|
||||
## YAML Ordering And Validation
|
||||
This package does not collect weather, choose an output destination, execute a
|
||||
provider, or persist data packages. The application passes its in-memory YAML
|
||||
to the Promptkit adapter as part of prepared report execution.
|
||||
|
||||
Serialization keeps `metadata` directly under `briefing`. Every other known stanza is placed in one category and emitted in category order while preserving its original module order:
|
||||
## Verification
|
||||
|
||||
| Category | Current stanzas |
|
||||
| --- | --- |
|
||||
| `applicable_risk_products` | alert digest, SPC convective outlooks |
|
||||
| `derived_summaries` | deterministic summaries, precipitation timing, outdoor windows, and planning values |
|
||||
| `narrative_products` | narrative forecast, discussions, and weather story |
|
||||
| `raw_data` | current conditions and hourly forecast |
|
||||
|
||||
`Validate` requires the v4 schema version, report identity and period fields, and at least one ordered briefing stanza. `MarshalYAML` validates before serializing. Normal application execution passes marshalled YAML directly to Promptkit.
|
||||
|
||||
Focused tests cover construction, curated exports, category ordering, serialization, and validation:
|
||||
Focused tests cover package construction, report-local dates, validation,
|
||||
curated snapshot exports, deterministic YAML grouping, and safe source-warning
|
||||
projection:
|
||||
|
||||
```sh
|
||||
go test ./internal/promptinput
|
||||
|
||||
@@ -1,34 +1,37 @@
|
||||
# Report Registry Internals
|
||||
|
||||
`internal/report` owns report identities, valid-period resolution, exact prompt identity and version, output names, default module composition, and Distributor path declarations. Public command syntax belongs in the [CLI reference](../cli.md); configuration aliases and overrides belong in the [configuration reference](../config.md).
|
||||
`internal/report` owns the in-process registry of report identities and the
|
||||
resolution of a report's valid period. Command names and configuration aliases
|
||||
belong to the [CLI reference](../cli.md) and [configuration
|
||||
reference](../config.md), respectively.
|
||||
|
||||
## Definitions And Resolution
|
||||
## Registry And Resolution
|
||||
|
||||
Each `Definition` declares a stable ID and display name, prompt ID and version, template and generated-text schema IDs, valid-period resolver, default output name, Distributor path templates, module list, and fixed batch eligibility. `Resolved` combines a definition with one valid period and run identity.
|
||||
`DefaultRegistry` supplies the maintained definitions. `Lookup` returns a
|
||||
definition by its internal ID, while `Resolve` combines it with a request time,
|
||||
location, and optional date to produce `Resolved`. The result carries the
|
||||
definition, generation time, timezone, and resolved valid period; its metadata
|
||||
and output-name helpers keep derived identity values consistent for callers.
|
||||
|
||||
| Report ID | Prompt version | Default profile | Period policy | Fixed batch flag | Default output |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `daily` | `2.0.0` | `weather-balanced` | Explicit local civil day | Dynamic Daily inclusion is app-owned | `daily-YYYY-MM-DD.md` |
|
||||
| `today` | `2.0.0` | `weather-balanced` | Selected or current local civil day | Morning | `today.md` |
|
||||
| `tomorrow` | `2.0.0` | `weather-balanced` | Next local civil day | Evening | `tomorrow.md` |
|
||||
| `hourly` | `2.0.0` | `weather-light` | Rolling six-hour interval | — | `hourly.md` |
|
||||
Definitions carry the internal collaborators needed downstream: prompt and
|
||||
template identity, module configuration, output naming, Distributor path
|
||||
templates, and fixed batch eligibility. The external prompt contract is owned
|
||||
by the [Promptkit integration guide](../integrations/promptkit.md), template
|
||||
surface by the [report template guide](../templates.md), and published
|
||||
Distributor paths by the [Distributor bundle guide](../integrations/distributor/pkg-bundle.md).
|
||||
|
||||
Daily derives its filename and run identity from the resolved valid-period start
|
||||
in the effective timezone, so multiple Daily items have distinct destinations
|
||||
and identifiers. Exact template fields and schema assets belong to [report
|
||||
templates](../templates.md) and [generated-text internals](generatedtext.md).
|
||||
Prompt assets own default profile selection; the registry stores no provider
|
||||
setting.
|
||||
`WithModuleOverrides` returns an independently cloned registry with replacement
|
||||
module configuration for recognized report IDs. The application owns batch
|
||||
planning and data-dependent inclusion; see [app orchestration
|
||||
internals](app-orchestration.md).
|
||||
|
||||
## Collaborators And Boundaries
|
||||
The registry never collects weather data, parses CLI flags, writes output,
|
||||
executes Promptkit, or delivers a report.
|
||||
|
||||
`DefaultRegistry`, `Lookup`, `Resolve`, and report-name helpers prevent callers from duplicating report identity rules. Registry overrides clone a recognized definition and replace its module list. `DistributorPathTemplates` are consumed by app orchestration; their rendered external bundle-path contract is documented in the [Distributor bundle guide](../integrations/distributor/pkg-bundle.md).
|
||||
## Verification
|
||||
|
||||
`morning` and `evening` are registry-owned batch names. Fixed flags declare Today and Tomorrow eligibility; app orchestration determines data-dependent Daily membership and the actual batch plan.
|
||||
|
||||
The registry never collects weather data, parses CLI flags, writes output, executes Promptkit, or delivers a report.
|
||||
|
||||
Focused tests cover definition completeness, command and alias lookup, period resolution, run IDs, output names, composition defaults, and override validation:
|
||||
Focused tests protect retained report definitions, period resolution, Daily
|
||||
run-ID disambiguation, and rejection of retired command or configuration names:
|
||||
|
||||
```sh
|
||||
go test ./internal/report
|
||||
|
||||
Reference in New Issue
Block a user