# Architecture Policy ## Purpose This policy defines Weatherreporter's system shape, ownership, dependency direction, and safety invariants. The [development guide](../development.md) owns the package inventory; focused documents in `docs/internal/` own implementation detail. ## System Shape Weatherreporter is a deterministic weather-report CLI. It collects normalized weather data, derives facts and modules, builds a curated YAML data package, executes exact-version Promptkit prompts, validates structured generated prose, and renders repository-owned Markdown in memory. Completed Markdown is atomically published to an operator-owned output destination and may then be uploaded through Distributor. The supported report products are Daily, Today, Tomorrow, and Hourly. A batch collects once, validates its complete candidate prompt/profile set before collection, then determines and validates every planned output destination before executing reports sequentially with one executor. It continues after independent report failures and sends a batch notification only after every planned report succeeds. ## Ownership And Boundaries - `internal/cli` owns command parsing, help, summaries, and one executor construction per action. - `internal/config` owns defaults, loading, validation, and secret loading. - `internal/app` owns in-memory workflow order, partial results, atomic output publication, and notification coordination through project-owned contracts. - Deterministic domain packages own weather derivation, report periods, modules, generated-text validation, and template contexts. - `internal/adapters/weatherapi`, `internal/adapters/promptkit`, and `internal/adapters/distributor` own their external dependency mechanics. Dependency-specific Promptkit types remain inside its adapter. The application does not parse flags, construct provider clients, or render provider output directly. ## Prompt Execution Invariants - Prompts receive curated module packages, never unbounded raw weather payloads. - Every execution validates the exact prompt version and output contract before collection. The selected profile is configured explicitly or declared by the prompt; unsupported direct-key profiles and missing reported credentials fail before collection. - Prompt and profile validation completes before weather collection. Raw output is validated before template rendering. - Generated text fills defined prose slots only. Deterministic facts remain authoritative and repository-owned templates produce all Markdown output. - Sensitive rendered prompts, schemas, input bodies, provider endpoints, and credentials never enter normal summaries or logs. They are written only to an explicit secure debug root when requested. ## Output, Notification, And Testing Invariants - Normal execution is stateless: it keeps weather data, prompt input, generated text, and render context in memory and creates no application-owned durable state. - Markdown writes are atomic at an operator-selected destination. A pre-publication failure, including cancellation observed immediately before publication, does not replace an existing destination; a notification failure does not remove a newly published output. - Distributor uploads use only the published Markdown output, never a scan of local files. Single notification follows publication; batch notification follows publication of every selected report. Batch counters describe report outcomes only; a failed batch notification is represented separately at the batch level. - Default tests are deterministic, offline, and use Promptkit/provider fakes rather than live provider calls. See the [testing policy](testing.md). ## Non-Goals Weatherreporter is not a weather-data ingestion service, general LLM orchestration framework, plugin platform, HTTP service, multi-user job system, or a replacement for Promptkit or Distributor.