| Expected commit from audit plan | `151c536cb91ebedb6039270b752bae219dfe33d0` (`Add comparison diagnostics to the future roadmap`) |
| Baseline difference | The audit uses the current `main`, one commit ahead of the expected commit. The intervening commit adds the audit workflow plan used to conduct this audit. |
| Branch | `main` |
| Initial worktree | Clean; `git status --porcelain=v1` produced no entries before the audit ledger was created. |
| Go toolchain | `go version go1.26.5 linux/amd64`; `go env GOVERSION` reported `go1.26.5`. |
| Graph refresh | Refreshed from the baseline checkout in `moderate` mode without a persisted artifact: 2,674 nodes and 11,572 edges. The indexer excluded `docs`, `examples`, embedded-asset directories, and test-data directories, so their inventories below come from tracked files rather than the graph. |
| Baseline exclusions | None. There were no pre-existing worktree changes. |
| Environmental limitations | None encountered. Validation was deterministic and offline. |
## Scope And Inventory
Stage 1 inventories the checked-out repository without judging subsystem
correctness or test sufficiency. The repository has 219 tracked files. Its Go
inventory contains 24 packages, 83 non-test source files, and 50 test files.
`docs/integrations/promptkit.md`, `docs/integrations/weatherapi.md`, and the
three documents under `docs/integrations/distributor/`;
- internal documents: all 17 tracked documents under `docs/internal/`; and
- release notes: the four tracked documents under `docs/releases/`.
The maintained examples are `examples/config.yml`,
`examples/minimal-config.yml`, and
`examples/weather-light-local-profile.yml`. Roadmaps are coordination records,
not canonical current-state documents; the four pre-existing roadmap files are
therefore outside the canonical count.
## Baseline Validation
| Command | Result | Evidence |
| --- | --- | --- |
| `go test ./...` | Pass | Exit 0. All 24 packages were evaluated; 22 package test suites passed and `cmd/weatherreporter` plus `internal/buildinfo` reported no test files. |
| `go run ./cmd/weatherreporter --help` | Pass | Exit 0. Help printed usage for help, version, four report generators, two batch commands, and comparison. |
| `git diff --check` | Pass | Exit 0 with no output on the clean pre-ledger baseline. |
| `go vet ./...` | Pass | Exit 0 with no diagnostics. |
Supplementary baseline commands were `git rev-parse HEAD`,
| Architecture and dependency direction | Assembled app and CLI tests; graph traces | 2 | Sufficient at the architectural boundary: direct imports are acyclic, external dependency types remain adapter-local, and representative workflow ordering and publication boundaries have focused tests. `AUD-001` records unused persistence APIs that do not participate in normal execution. |
| Report identity, periods, dates, and timezones | `internal/report`, `internal/timeutil`, plus focused `internal/app` and `internal/forecast` callers | 3 | Partly insufficient. Registry identities, alias policies, batch membership, civil-day boundaries, and elapsed six-hour periods are coherent and exercised. `AUD-002` records incorrect wall-clock windows on daylight-saving transition days, and `AUD-003` records the missing regression test for Daily run-ID uniqueness across dates. |
module, prompt, rendering, comparison, and notification correctness remains
assigned to Stages 3-18. Cross-cutting complexity, deduplication, and full
documentation coherence remain assigned to Stages 22-24.
#### Boundary Accounting
| Normative boundary or invariant | Implementation owner and evidence | Disposition |
| --- | --- | --- |
| Binary entry and CLI ownership | `cmd/weatherreporter.main` calls `cli.Run`; `internal/cli` owns action parsing, config loading, executor construction, and bounded result output. Graph traces place app calls below action resolution. | Matches policy. |
| Configuration ownership | `internal/config` owns defaults, YAML loading, normalization, secrets, and validation. CLI loads config and passes effective values down; app does not parse config files. | Matches policy; the config-to-briefing validation edge is routed to Stages 4, 8, and 23. |
| Application orchestration | `GenerateDetailed`, `RunBatchDetailed`, and `compareDetailed` sequence preflight, collection, preparation, execution, publication, and notification through repository-owned values and interfaces. No lower package imports app. | Matches policy; retained as `RET-001`. |
| Report and domain ownership | `report`, `timeutil`, `weatherdata`, `forecast`, `facts`, `module`, `briefing`, `promptinput`, `generatedtext`, and `reporttemplate` form one-way deterministic dependencies below app. | Matches policy at package level; local rules remain for Stages 3 and 7-13. |
| Prompt execution boundary | `promptexec.Executor` is dependency-neutral. CLI constructs the Promptkit adapter once per action, app consumes only `promptexec` requests/results, and the prepared-report data flow supplies curated serialized module packages. | Matches policy; retained as `RET-002`. |
| Weather API boundary | App calls its `Collector` interface; the production implementation delegates through `collect.Run` to `adapters/weatherapi.FetchBundle`, which returns normalized `weatherdata.Bundle`. Production HTTP imports occur only in external adapters. | Matches policy; retained as `RET-004`. |
| Distributor boundary | App owns notification timing and repository request/result types; `distributorNotifier` translates them to adapter-local types and the adapter alone imports the Distributor dependency. Comparison exposes no notifier path. | Matches policy. |
| Prompt preflight and curated inputs | Generate inspects the exact prompt/profile before `collectWeather`; batch inspects all candidates before its one collection; comparison inspects prompt and all profiles before collection, then calls `prepareReport` once. Data-flow traces reach `promptinput.Build` and `MarshalYAML`, not raw bundle serialization into Promptkit. | Matches policy at workflow level; detailed checks remain for Stages 10, 11, 14, and 18. |
| Single output and notification order | `publishPromptReport` checks context, calls `fileutil.WriteFileAtomic`, records the path, and only then calls `notifyReport`. Focused tests cover pre-publication preservation and notification ordering. | Matches policy; publication split retained as `RET-003`. |
| Batch output and notification order | `RunBatchDetailed` validates every planned path before sequential execution, suppresses item notification, continues across item failures, and calls `notifyBatch` only after the loop. Focused tests cover preflight, partial failure, and notification-after-publication. | Matches policy at workflow level; detailed review remains for Stage 16. |
| Comparison publication | App preflights before external work and again before publication. `internal/comparison` owns bundle validation, guarded replacement, staging, commit, restoration, and cleanup results. The comparison request has no notifier and the trace does not reach Distributor. | Matches policy at workflow level; detailed review remains for Stages 17-18. |
| Stateless execution | Normal traces retain preparation and execution values in memory. Production filesystem writes are limited to selected Markdown publication, selected comparison bundles, explicit prompt-debug capture, and the unreachable helpers in `AUD-001`; no cache, workspace, history, receipt, or resume owner appears in the package graph. | Matches normal-runtime policy; `AUD-001` records the unused persistence surface. |
| Dependency cycles and direction | The compiler-derived direct-import inventory is acyclic. Entry packages point inward, adapters do not import app/CLI, domain packages do not import orchestration, and no external dependency type appears outside its production adapter. | Matches policy. |
#### Commands And Evidence
- Refreshed graph project `home-eric-Workspace-weatherreporter` in moderate
mode. The graph's branch identity remains production baseline `e7c7262`;
Stage 1's intervening commit changes only this excluded audit document.
- Used graph architecture views for structure, dependencies, entry points,
hotspots, boundaries, layers, and clusters; queried the graph schema and
direct import edges.
- Used graph search, snippets, inbound/outbound call traces, and data-flow
traces for `main`, `cli.Run`, `GenerateDetailed`, `RunBatchDetailed`,
### Stage 3: Audit Report Identity And Time Foundations
- Status: Complete.
- Scope reviewed: all production and focused-test code in `internal/report`
and `internal/timeutil`; report and timezone contracts in `docs/cli.md`,
`docs/config.md`, and `docs/internal/report-registry.md`; and the focused
`internal/app` and `internal/forecast` callers that consume batch membership,
run IDs, civil periods, clock windows, and hourly coverage.
- Exclusions: Effective configuration validation and CLI date parsing remain
assigned to Stages 4-5. Forecast derivation beyond the time boundary remains
assigned to Stage 7. Module, prompt, schema, and template compatibility
remains assigned to Stages 8 and 10-13. Batch notification and Distributor
idempotency behavior remains assigned to Stage 16, and documentation-wide
coherence remains assigned to Stage 24.
#### Contract Accounting
| Contract or risk | Implementation and caller evidence | Disposition |
| --- | --- | --- |
| Stable report identities | The default registry contains exactly Daily, Today, Tomorrow, and Hourly. Each definition carries the documented prompt `2.0.0`, matching template/schema identity, modules, output name, and Distributor paths; focused registry tests assert the retained surface. | Matches the registry contract; explicit definitions retained as `RET-005`. Asset compatibility remains for later owner stages. |
| Alias resolution | Command lookup accepts exact current command names. Config lookup separately normalizes whitespace, case, and hyphens. Both reject retired aliases in focused tests. | Matches the distinct boundary contracts; separation retained as `RET-006`. |
| Batch membership and ordering | Morning explicitly plans Today then Tomorrow before eligible Daily dates; Evening explicitly plans Tomorrow before eligible Daily dates. Focused app tests cover ordering, flags, multiple Daily dates, and no eligible dates. | Matches CLI and registry contracts. Detailed partial-success and notification semantics remain for Stage 16. |
| Report period policy | Daily requires an explicit date; Today uses an explicit date or current local date; Tomorrow selects the next local civil day; Hourly spans six elapsed hours from the injected clock. `Resolve` defaults a missing location to UTC and a zero clock to the system clock. | Matches documented selection policy; calendar and elapsed policies retained separately as `RET-007`. |
| Civil-day and hourly DST behavior | `CivilDay` uses local midnight plus one calendar day, and batch hourly coverage walks actual instants, correctly accommodating 23-hour and 25-hour dates. Focused batch tests exercise DST civil days. | Sufficient for the reviewed policy. |
| Configured clock windows | `ClockWindow` adds elapsed clock durations to local midnight. The only production path reaches `forecast.ResolveDayparts`, daily summaries, and facts. Fixed-zone tests do not exercise either DST transition. | Incorrect on DST dates; recorded as `AUD-002`. |
| Date and timezone parsing | `ParseLocalDate` uses strict `YYYY-MM-DD` parsing in the selected location. `LoadLocation` covers IANA names, `America/` fallback, documented aliases, fixed US abbreviations, and signed offsets, returning contextual errors for invalid input. | Implementation is coherent for Stage 3. Effective config validation and CLI error presentation remain for Stages 4-5. |
| Clock control | All report resolvers accept an injected `Now`; only zero-valued input falls back to `time.Now`. Focused report and batch tests use fixed clocks. | Sufficient for deterministic period selection. |
| Daily output and run identity | Daily output names derive from the resolved valid-start date, and Daily run IDs append that date so same-clock multi-date products remain distinct. The downstream batch-notification map rejects duplicate IDs. | Implementation is coherent, but the identity invariant lacks a focused behavior test; recorded as `AUD-003`. |
| Half-open period operations | `Period.Valid`, `Contains`, `Overlaps`, and `Intersection` consistently use `[start,end)` semantics, and focused tests protect overlap boundaries. | Matches the internal period contract. |
#### Commands And Evidence
- Used graph search, source snippets, and inbound/outbound traces for the four
report definitions, registry construction and lookup, command/config mapping,
batch mapping and planning, `Resolve`, every period resolver, `CivilDay`,
`ClockWindow`, `ParseLocalDate`, `LoadLocation`, period overlap operations,