# Collection Internals This document describes the app-facing upstream collection boundary in `internal/collect`. ## Purpose `internal/collect` is the canonical package used by app workflows to collect upstream Weather API data. It constructs the Weather API adapter, fetches a normalized bundle, and returns that bundle without applying report selection or batch policy. ## Contract Inputs: - `collect.Request`, containing the effective `config.Config` - `context.Context` for cancellation Output: - `collect.Result`, containing `*weatherdata.Bundle` `Run` returns an actionable error when Weather API adapter construction or bundle fetch fails. The package does not derive `facts.CollectedFacts`, build modules, resolve report periods, select reports, write state, invoke Scriptorium, or notify distributor. ## App Usage `internal/app` owns a narrow `Collector` interface for orchestration tests. The default implementation calls `collect.Run`. Single-report generation collects once, resolves the requested report, and passes the explicit collection into report generation. Batch generation collects once before planning and passes the same collection into each planned report. If collection returns no bundle, app orchestration returns an error before report generation. ## Boundaries Weather API HTTP details stay in `internal/adapters/weatherapi`. The collection package returns normalized `weatherdata` only. It must not know about report IDs, prompt IDs, batch names, Daily eligibility, module composition, Recent Changes, state paths, or Scriptorium arguments. ## Tests Inspect: - `internal/collect/collect_test.go` - `internal/app/app_test.go` ## Invariants - App-facing Weather API collection goes through `internal/collect`. - Collection returns normalized source data, not report facts or prompt input. - Report and batch policy belongs outside `internal/collect`.