# Collection Internals `internal/collect` is the application-facing boundary for collecting the 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). ## 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}`. 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. 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. 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. 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. The required hourly product must contain one or more periods with usable time bounds. An invalid hourly product fails collection before derivation begins. ## 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`.