diff --git a/docs/roadmap/audit.md b/docs/roadmap/audit.md index 64bebff..c0dd0b3 100644 --- a/docs/roadmap/audit.md +++ b/docs/roadmap/audit.md @@ -1,6 +1,7 @@ # Repository Audit Ledger -Status: In progress; Stages 1-24 complete. +Status: In progress; Stages 1-24 and 26 complete. Stage 25 was interrupted +before its evidence was recorded. This temporary roadmap document is the evidence ledger for the staged audit defined by [the audit plan](audit-plan.md). It records audit evidence and @@ -211,7 +212,15 @@ the scoped atomic-visibility wording otherwise agree with their executable or historical owners. Existing implementation defects that violate correctly stated intended contracts remain assigned to their earlier findings rather than being duplicated as documentation defects. -Subsystem conclusions and final disposition remain pending the later stages. +Stage 26 rechecked the two high-severity prompt-contract findings and the +security, diagnostic-boundary, cancellation, and destructive-publication +findings against current assets, source, and focused tests. It confirmed 74 +distinct findings and rejected four standalone entries after consolidating +them into broader root-cause findings. All 61 retained decisions remain +supported, all routed investigation questions now resolve to a finding or a +retained decision, and no high-impact uncertainty requires a supplemental +investigation stage. Remediation acceptance, priority, and implementation +sequencing remain exclusively Stage 27 work. ## Baseline Metadata @@ -361,9 +370,9 @@ inventory commands, graph index refresh, and graph architecture inspection. | 21 | Audit test durability, duplication, and maintenance cost | Complete | | 22 | Audit cross-cutting efficiency and complexity | Complete | | 23 | Audit cross-cutting refactoring and deduplication opportunities | Complete | -| 24 | Audit documentation coherence and executable contracts | Pending | +| 24 | Audit documentation coherence and executable contracts | Complete | | 25 | Run dynamic robustness and final diagnostic validation | Pending | -| 26 | Verify, consolidate, and triage findings | Pending | +| 26 | Verify, consolidate, and triage findings | Complete | | 27 | Produce the remediation roadmap and close the audit | Pending | ## Risk-To-Test Coverage @@ -374,14 +383,14 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. | Risk area | Current test owner or evidence source | Audit stage | Coverage assessment | | --- | --- | ---: | --- | -| 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. | +| 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. The unused persistence APIs first recorded by rejected standalone `AUD-001` are consolidated into confirmed `AUD-072`. | | 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. | | Configuration, validation, and secrets | `internal/config`, focused `internal/cli` and Promptkit adapter mapping, maintained examples | 4 | Partly insufficient. Defaults, precedence, known-field parsing, active URL/duration/template checks, output-path preservation, profile-source rules, secret redaction, and examples are exercised. `AUD-004` through `AUD-007` record unsupported missing-source keys, blank notification identities, constructed-report override inconsistency, and non-atomic secret environment mutation. | | CLI parsing, output, and exit behavior | `cmd/weatherreporter`, `internal/cli`, representative app-facing CLI tests | 5 | Partly insufficient. Command/flag ownership, paths, one-executor mapping, stream separation, quiet mode, comparison safe errors, and visible result/exit rules are coherent. `AUD-008` records missing signal cancellation, `AUD-009` records late generate date validation, and `AUD-010` records missing assembled non-comparison CLI protection. | | Weather transport and normalized collection | `internal/adapters/weatherapi`, `internal/collect`, `internal/weatherdata` | 6 | Partly insufficient. All eight source requests, required/optional policy, checked-empty products, retryable source statuses, cancellation, normalized provenance, and collection error ownership have focused offline coverage. `AUD-011` through `AUD-015` record unsupported schemes, unsafe response-body diagnostics, an unenforced body-size limit, structurally invalid required hourly periods, and overbroad warmup retries. | | Forecast and fact derivation | `internal/forecast`, `internal/facts` | 7 | Partly insufficient. Half-open selection, stable ordering, alert parsing and clipping, precipitation-window grouping, report-family selection, and SPC checked-empty behavior have focused owners. `AUD-016` through `AUD-019` record unit collapse, overnight alert omission, invalid percentage acceptance, and incomplete ice-text classification. | -| Module and briefing contracts | `internal/module`, `internal/briefing` | 8-9 | Partly insufficient. Registry/default composition, report support, missing optional sources, checked-empty alerts, output identity, ordering, current/hourly prompt curation, precipitation timing, and SPC selection have focused owners. `AUD-020` through `AUD-028` record inconsistent pointer options, false weather-story availability, permissive snapshot schema validation, apparent-temperature mislabeling, daypart-key collisions, inconsistent planning identities, incomplete outdoor hazard scoring, incorrect subzero phrases, and stale official SPC descriptions. | -| Prompt inputs, embedded assets, and execution contracts | `internal/promptinput`, `internal/promptassets`, `internal/promptexec` | 10 | Partly insufficient. Prompt/profile/schema identities, deterministic grouping, validation/execution result categories, safe bounded errors, explicit debug, and copy isolation have focused owners. `AUD-029` through `AUD-033` record raw warning types and transport paths crossing the boundary, stale embedded prompt paths, incorrect SPC locality instructions, permissive YAML loading, and missing serialization-failure coverage. | +| Module and briefing contracts | `internal/module`, `internal/briefing` | 8-9 | Partly insufficient. Registry/default composition, report support, missing optional sources, checked-empty alerts, output identity, ordering, current/hourly prompt curation, precipitation timing, and SPC selection have focused owners. Confirmed `AUD-020`, `AUD-021`, and `AUD-023` through `AUD-028` record the distinct defects; rejected standalone `AUD-022` is consolidated into the dormant compatibility decision in `AUD-072`. | +| Prompt inputs, embedded assets, and execution contracts | `internal/promptinput`, `internal/promptassets`, `internal/promptexec` | 10 | Partly insufficient. Prompt/profile/schema identities, deterministic grouping, validation/execution result categories, safe bounded errors, explicit debug, and copy isolation have focused owners. Confirmed `AUD-029` through `AUD-031` and `AUD-033` record the distinct boundary and contract gaps; rejected standalone loader-hardening entry `AUD-032` is consolidated into `AUD-072`. | | Promptkit boundary and sensitive debug output | `internal/adapters/promptkit`, `internal/promptdebug` | 11 | Partly insufficient. Exact prompt/profile inspection, source precedence, inline execution, credential checks, cancellation, safe classified errors, callback ordering, debug opt-in, static symlink rejection, restrictive modes, atomic replacement, and distinct concurrent captures have focused owners. `AUD-034` and `AUD-035` record incomplete credential redaction and a check/use symlink race. | | Generated-text validation | `internal/generatedtext` | 12 | Partly insufficient. The four current registry definitions dispatch to typed validators with coherent required-field and normalization behavior, and schema bytes are independently copied. `AUD-036` through `AUD-039` record report-independent catalog matching, case-insensitive Go field aliases, unbounded prose/diagnostics, and duplicated or misplaced contract tests. | | Render contexts and templates | `internal/generatedtext`, `internal/reporttemplate` | 13 | Partly insufficient. Typed module extraction, deterministic daypart ordering, report-specific sections, partial conditions, template lookup, and semantic output assertions are coherent. `AUD-040` through `AUD-042` record conflicting report identities, structural Markdown injection, and Today's empty daypart section. | @@ -392,18 +401,19 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. | Comparison concurrency and CLI behavior | `internal/app`, `internal/cli` | 18 | Partly insufficient. Explicit profiles are preflighted sequentially, one immutable prepared package feeds concurrent profile-local executions, goroutines join, slice positions lock durable/CLI order, partial bundles publish coherently, and safe summaries preserve committed paths and fail the action on any error. `AUD-058` records a missing mixed failure/cancellation case and the resulting overwrite of an already completed profile failure. | | Test hermeticity and execution hygiene | All Go tests, fixtures, test assets, and helper mechanisms | 19 | Partly insufficient. The suite is offline, uses controlled clocks/roots/environment for almost every stateful case, has no subprocesses or automatic golden updates, passes race and shuffled-repeat checks, and succeeds with a scrubbed environment and broken external proxies. `AUD-059` records one ambient credential assumption; `AUD-060` records unguarded symlink-capability assumptions. | | Test risk coverage and ownership | Repository-wide suite | 20 | Partly insufficient. Consequential contracts have narrow owners and representative cross-boundary workflows; every identified missing regression is already attached to the production or test-gap finding for the defect it would catch. Coverage diagnostics found no additional unowned critical branch. Accepted omissions are thin entry-point/delegation wrappers, defensive accessors, and dormant helpers already routed under `AUD-001`; broad duplication and durability remain Stage 21. | -| Test durability, duplication, and maintenance cost | Repository-wide suite | 21 | Partly insufficient. Most tests assert stable behavior with direct fixtures and appropriately narrow fakes. `AUD-039`, `AUD-061`, and `AUD-063` identify duplicated or implementation-coupled assertions; `AUD-062` identifies avoidable production waits; `AUD-064` identifies incomplete failure cleanup. Each consolidation retains a named behavioral owner. | +| Test durability, duplication, and maintenance cost | Repository-wide suite | 21 | Partly insufficient. Most tests assert stable behavior with direct fixtures and appropriately narrow fakes. Confirmed `AUD-039` now owns both duplicated generated-text semantics and cross-owner render assertions formerly split into rejected `AUD-063`; `AUD-061` identifies one implementation-coupled assertion, `AUD-062` avoidable production waits, and `AUD-064` incomplete failure cleanup. Each consolidation retains a named behavioral owner. | | Cross-cutting efficiency | Graph metrics, workflow traces, and focused latency/allocation diagnostics | 22 | Partly insufficient. Fixed-size registries, service-sized derivation, template parsing, batch composition, and ordinary profile fan-out are proportionate. `AUD-065` records one redundant Weather API request plus serial independent source fetches; `AUD-066` records repeated full comparison-bundle reads during replacement. | | Cross-cutting maintainability | Graph similarity, change history, caller traces, and focused structural review | 23 | Partly insufficient. `AUD-067` through `AUD-073` identify duplicated canonicalization/template/date/requirement policy, parallel metadata authority, dormant internal surfaces, and unsafe duplicate capitalization. Important report, prompt-curation, safety-copy, validation, and orchestration similarities remain explicit under `RET-053` through `RET-058`. | | Documentation and executable-contract coherence | Canonical documents, code, schemas, templates, examples | 24 | Partly insufficient. `AUD-074` through `AUD-078` record CLI/help drift, stale internal flow/API/test claims, completed-roadmap duplication, an implicit concurrent-executor requirement, and incomplete configuration normalization/bounds. Other volatile identities and maintained examples match their executable owners; linked summaries, historical release notes, and the accepted ADR remain appropriately distinct. | | Dynamic robustness and diagnostic checks | Repository-wide deterministic checks | 25 | Pending | +| Finding verification and triage | All findings, retained decisions, routed questions, validation records, and coverage entries | 26 | Complete. Seventy-four findings are confirmed and four duplicate standalone entries are rejected into their named root-cause owners. No candidate or deferred status remains; all confirmed entries retain actionable test implications and validation criteria. | ## Findings ### AUD-001: Unused persistence helpers remain after the stateless redesign - Stage: 2 -- Status: candidate +- Status: rejected - Severity: low - Confidence: high - Category: architecture @@ -437,13 +447,17 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. - Validation: Graph and text searches show no remaining production references to the retired helpers; `go test ./...` passes; normal output, comparison, and debug-publication tests remain unchanged and pass. -- Related findings: none +- Disposition: Rejected as a standalone finding. Its evidence is sound, but + the unused writers are one part of the dormant compatibility surface already + consolidated under `AUD-072`; a separate recommendation would split one + ownership decision without changing its priority or validation. +- Related findings: `AUD-072` - Remediation reference: pending ### AUD-002: Clock windows shift on daylight-saving transition days - Stage: 3 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -480,7 +494,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-003: Daily run-ID uniqueness lacks a focused contract test - Stage: 3 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: testing @@ -518,7 +532,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-004: Unsupported missing-source keys are silently accepted - Stage: 4 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -556,7 +570,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-005: Single-report notification identities may render blank - Stage: 4 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -592,7 +606,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-006: Constructed report overrides depend on inaccessible presence flags - Stage: 4 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -632,7 +646,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-007: Failed configuration loads can leave secrets applied - Stage: 4 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: security @@ -667,7 +681,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-008: Process interrupts do not cancel active workflows - Stage: 5 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -706,7 +720,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-009: Generate validates report dates after constructing its executor - Stage: 5 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -745,7 +759,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-010: Assembled non-comparison CLI result paths lack durable tests - Stage: 5 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: testing @@ -786,7 +800,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-011: Unsupported Weather API URL schemes fail only at transport - Stage: 6 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -821,7 +835,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-012: Weather API failures expose upstream response bodies - Stage: 6 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: security @@ -857,7 +871,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-013: The Weather API response limit silently truncates bodies - Stage: 6 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -893,7 +907,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-014: Required hourly periods can lack usable time bounds - Stage: 6 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -929,7 +943,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-015: Weather API warmup retries permanent HTTP failures - Stage: 6 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: correctness @@ -960,7 +974,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-016: Metric fallback values lose their unit during daypart derivation - Stage: 7 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1002,7 +1016,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-017: Overnight dayparts omit alerts that begin after midnight - Stage: 7 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1036,7 +1050,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-018: Invalid precipitation percentages flow into derived summaries - Stage: 7 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1070,7 +1084,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-019: Ordinary “icy” forecast text does not set the ice indicator - Stage: 7 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: correctness @@ -1099,7 +1113,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-020: Pointer-shaped AFD options pass validation but fail construction - Stage: 8 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1138,7 +1152,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-021: Empty weather-story data is published as available - Stage: 8 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1174,7 +1188,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-022: Module snapshots accept unsupported schema versions - Stage: 8 -- Status: candidate +- Status: rejected - Severity: low - Confidence: high - Category: compatibility @@ -1199,13 +1213,18 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. current constructor/version and duplicate-output tests. - Validation: Only the current module snapshot schema passes validation; all normal snapshot construction and downstream consumers remain unchanged. -- Related findings: none +- Disposition: Rejected as a standalone compatibility fix. The only producer + is `NewSnapshot`, which always writes the current constant, and no decoded or + external snapshot workflow exists. The narrow validation inconsistency is + retained as part of the broader no-owner decision in `AUD-072`; hardening it + independently would add a contract for a surface the repository may retire. +- Related findings: `AUD-072` - Remediation reference: pending ### AUD-023: Apparent temperature is published as heat index - Stage: 9 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1243,7 +1262,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-024: Normalized daypart keys can silently overwrite summaries - Stage: 9 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1277,7 +1296,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-025: Planning applies configurable daypart identities inconsistently - Stage: 9 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1313,7 +1332,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-026: Outdoor-window ranking ignores snow, ice, and fog - Stage: 9 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1346,7 +1365,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-027: Subzero temperatures are rendered as positive zero-degree bands - Stage: 9 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1377,7 +1396,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-028: Embedded official SPC category descriptions have drifted - Stage: 9 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1418,7 +1437,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-029: Raw source warnings cross the curated prompt boundary - Stage: 10 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: security @@ -1457,7 +1476,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-030: The shared prompt instructs nonexistent briefing paths - Stage: 10 -- Status: candidate +- Status: confirmed - Severity: high - Confidence: high - Category: correctness @@ -1494,7 +1513,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-031: The shared prompt overstates SPC product locality - Stage: 10 -- Status: candidate +- Status: confirmed - Severity: high - Confidence: high - Category: correctness @@ -1532,7 +1551,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-032: The exported YAML loader accepts malformed package shapes - Stage: 10 -- Status: candidate +- Status: rejected - Severity: low - Confidence: high - Category: correctness @@ -1562,13 +1581,18 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. - Validation: Each malformed probe fails with bounded context, one canonical document round-trips deterministically, and no production execution behavior changes. -- Related findings: none +- Disposition: Rejected as a standalone hardening finding. The malformed-input + probes are reproducible, but graph and text searches show that tests are the + loader's only callers. `AUD-072` owns the prior question—retire the loader or + identify a real consumer—so prescribing strict decoding first has + insufficient cost-benefit evidence. +- Related findings: `AUD-072` - Remediation reference: pending ### AUD-033: Stanza serialization failures lack a focused contract test - Stage: 10 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: testing @@ -1603,7 +1627,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-034: Prompt-debug credential redaction misses common aliases and URL forms - Stage: 11 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: security @@ -1643,7 +1667,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-035: Prompt-debug symlink checks can be raced before writes - Stage: 11 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: security @@ -1682,7 +1706,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-036: The generated-text catalog accepts a known pair for the wrong report - Stage: 12 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1721,7 +1745,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-037: Typed decoding accepts property names rejected by the schema - Stage: 12 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: correctness @@ -1759,7 +1783,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-038: Generated prose and decoder diagnostics have no size boundary - Stage: 12 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: reliability @@ -1799,15 +1823,16 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. - Related findings: none - Remediation reference: pending -### AUD-039: Generated-text contract tests duplicate policy across owners +### AUD-039: Generated-text tests duplicate semantic and rendered-output ownership - Stage: 12 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: testing -- Area: `internal/generatedtext/{daily,today,tomorrow,day_style}_test.go` and - schema assertions in `internal/reporttemplate/reporttemplate_test.go` +- Area: `internal/generatedtext/{daily,today,tomorrow,day_style,render_context}_test.go` + and schema/render assertions in + `internal/reporttemplate/reporttemplate_test.go` - Evidence: Daily, Today, and Tomorrow each carry nearly line-for-line copies of normalization and malformed-input tables, while the shared day-style suite repeats summary, discussion, normalization, empty timing, missing @@ -1816,7 +1841,10 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. repeats four schema-shape assertions, including three duplicated day-style blocks, even though `reporttemplate` owns Markdown assets and `promptassets_test.go` already owns the schema inventory, strict-object - shape, required fields, identity, and copy isolation. + shape, required fields, identity, and copy isolation. The four full + render-context tests additionally assert substantial report-specific + Markdown fragments and ordering already owned by reporttemplate; the two + large suites changed together 11 times with a 0.73 graph coupling score. - Contract at risk: Similar public validators should remain independently protected without copying shared semantics, and schema tests should reside with the asset owner rather than an unrelated template package. @@ -1828,20 +1856,23 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. thin per-exported-validator identity/type case. Move complete schema-shape ownership to `promptassets`; keep only a generated-text integration contract that compares schema acceptance with typed validation where their semantics - intentionally overlap. Remove schema assertions from `reporttemplate`. + intentionally overlap. Remove schema assertions from `reporttemplate`. Keep + report-specific typed projections in generatedtext and Markdown semantics in + reporttemplate, with one compact real-context render smoke test proving that + the boundaries compose. - Test implications: Preserve distinct Hourly behavior and each public report identity while deleting repeated semantic cases. A mechanical refactor of a private day-style helper should not require unrelated test edits. - Validation: The leaner suite still fails for a wrong report dispatch, schema/type disagreement, required-field regression, or normalization change, and report-template tests fail only for template/render behavior. -- Related findings: `AUD-037` +- Related findings: `AUD-037`, `AUD-063` - Remediation reference: pending ### AUD-040: Render contexts accept conflicting report identities - Stage: 13 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -1885,7 +1916,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-041: Dynamic prose can impersonate deterministic Markdown sections - Stage: 13 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: security @@ -1930,7 +1961,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-042: Today can render a daypart heading with no rows or fallback - Stage: 13 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: correctness @@ -1962,7 +1993,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-043: Generated-text compatibility is validated after collection - Stage: 14 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -2005,7 +2036,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-044: Execution provenance is accepted without reconciliation - Stage: 14 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -2053,7 +2084,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-045: Single-report publication replaces non-regular destinations - Stage: 15 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -2094,7 +2125,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-046: Valid long output names fail through the temporary-name pattern - Stage: 15 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: correctness @@ -2138,7 +2169,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-047: Cancellation is not checked at the publication linearization point - Stage: 15 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: reliability @@ -2180,7 +2211,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-048: Unsupported Distributor endpoint forms fail only after publication - Stage: 16 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -2221,7 +2252,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-049: Distributor response text crosses into normal batch diagnostics - Stage: 16 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: security @@ -2261,7 +2292,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-050: Distributor response bodies have no size boundary - Stage: 16 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: reliability @@ -2297,7 +2328,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-051: Mid-batch cancellation is flattened into ordinary report failures - Stage: 16 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: reliability @@ -2341,7 +2372,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-052: Distributor adapter tests bypass the production HTTP boundary - Stage: 16 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: testing @@ -2379,7 +2410,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-053: Comparison recognition accepts ambiguous manifest fields - Stage: 17 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: compatibility @@ -2418,7 +2449,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-054: Manifest validation does not enforce canonical profile report names - Stage: 17 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: compatibility @@ -2459,7 +2490,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-055: Replacement ignores cancellation after moving the prior bundle - Stage: 17 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: reliability @@ -2499,7 +2530,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-056: Cleanup errors can leave an invalid retained backup - Stage: 17 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: reliability @@ -2541,7 +2572,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-057: Long comparison destinations fail through derived sibling names - Stage: 17 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: correctness @@ -2578,7 +2609,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-058: Late cancellation overwrites completed profile failures - Stage: 18 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: correctness @@ -2623,7 +2654,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-059: Missing-credential test depends on the ambient environment - Stage: 19 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: test reliability @@ -2659,7 +2690,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-060: Symlink tests assume host creation capability - Stage: 19 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: test portability @@ -2699,7 +2730,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-061: SPC policy constants have a redundant implementation-coupled test - Stage: 21 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: test maintenance @@ -2731,7 +2762,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-062: Two integration tests pay production retry and polling intervals - Stage: 21 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: test maintenance @@ -2768,7 +2799,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-063: Render-context tests duplicate template output ownership - Stage: 21 -- Status: candidate +- Status: rejected - Severity: low - Confidence: high - Category: test maintenance @@ -2802,13 +2833,17 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. - Validation: Breaking any typed projection fails generatedtext; breaking any report template or partial fails reporttemplate; making the two boundaries incompatible fails the retained integration case. +- Disposition: Rejected as a separate finding because it is the cross-package + instance of the same duplicated contract ownership recorded by `AUD-039`. + Keeping two remediation entries would create overlapping edits and two + validation plans for one consolidation boundary. - Related findings: `AUD-039` - Remediation reference: pending ### AUD-064: Comparison test failure exits can leave workers blocked - Stage: 21 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: test diagnostics @@ -2843,7 +2878,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-065: Weather collection duplicates one source and serializes independent requests - Stage: 22 -- Status: candidate +- Status: confirmed - Severity: medium - Confidence: high - Category: efficiency @@ -2889,7 +2924,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-066: Comparison replacement repeatedly rereads complete bundles - Stage: 22 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: efficiency @@ -2934,7 +2969,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-067: Daypart key canonicalization has two independent owners - Stage: 23 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: duplication @@ -2974,7 +3009,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-068: Distributor single and batch templates duplicate one parser - Stage: 23 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: duplication @@ -3010,7 +3045,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-069: Preparation retains parallel metadata authorities and unused render surfaces - Stage: 23 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: architecture @@ -3059,7 +3094,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-070: Fact requirement policy spans constants, declarations, and switches - Stage: 23 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: architecture @@ -3102,7 +3137,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-071: Generate and comparison repeat report-date policy at four sites - Stage: 23 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: duplication @@ -3139,14 +3174,16 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. - Related findings: `AUD-009` - Remediation reference: pending -### AUD-072: Dormant internal compatibility surfaces have no workflow owner +### AUD-072: Dormant internal compatibility and persistence surfaces have no workflow owner - Stage: 23 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: architecture -- Area: `internal/promptinput.LoadYAML`, +- Area: `internal/promptinput.{LoadYAML,Save}`, + `internal/adapters/weatherapi.SaveBundle`, + `internal/fileutil.WriteJSONAtomic`, `internal/module.Snapshot.Validate`, `internal/forecast.{DifferenceAtLeast,CrossesAtOrAbove,CrossesBelow}`, `internal/weatherdata.AlertRun.Raw`, and the normalized-JSON return from `internal/generatedtext` validators @@ -3175,7 +3212,10 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. and adapter assignments; and simplify the internal validator/handler result to the typed value plus error. If a concrete tooling consumer is identified before remediation, document and test its narrow contract instead of - retaining all surfaces speculatively. + retaining all surfaces speculatively. Make the same owner decision for + module snapshot decoding/version validation: retire the exported + compatibility implication if snapshots remain construction-only, or enforce + the exact supported version when a real decoding boundary is introduced. - Test implications: Preserve Build/Validate/MarshalYAML execution tests, forecast behavior that uses real threshold decisions, alert item parsing and provenance hashes, typed normalization semantics, schema agreement, and all @@ -3185,13 +3225,13 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. - Validation: Graph and text searches show no remaining caller or field reference, prompt YAML and rendered reports remain unchanged, alert source hashes still cover accepted payloads, and the repository suite passes. -- Related findings: `AUD-001`, `AUD-032`, `AUD-038`, `AUD-039` +- Related findings: `AUD-001`, `AUD-022`, `AUD-032`, `AUD-038`, `AUD-039` - Remediation reference: pending ### AUD-073: Duplicate capitalization helpers disagree on Unicode safety - Stage: 23 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: duplication @@ -3226,7 +3266,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-074: CLI help and internal guidance disagree with action behavior - Stage: 24 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: documentation @@ -3270,7 +3310,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-075: Internal guides describe nonexistent APIs, flows, and tests - Stage: 24 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: documentation @@ -3318,7 +3358,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-076: Completed comparison roadmaps duplicate current contracts - Stage: 24 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: documentation @@ -3364,7 +3404,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-077: Concurrent executor substitutability is only implicit - Stage: 24 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: documentation @@ -3406,7 +3446,7 @@ with evidence about meaningful risks, test ownership, gaps, and duplication. ### AUD-078: Configuration normalization and timezone bounds are underdocumented - Stage: 24 -- Status: candidate +- Status: confirmed - Severity: low - Confidence: high - Category: documentation @@ -4607,6 +4647,12 @@ Stage 24 routed these investigation leads to their assigned later stages: Stage 26 decides `AUD-069`/`AUD-072`. Their focused docs should narrow or disappear with that code change, not ahead of it. +Stage 26 resolved the accumulated leads. Each now maps to a confirmed finding, +a rejected duplicate with a named consolidated owner, or a retained decision. +No unexplained failure, unresolved high-impact question, or supplemental +investigation stage remains. The choice to accept, defer, or sequence +remediation is intentionally left to Stage 27. + ## Stage Log ### Stage 1: Establish The Baseline And Audit Ledger @@ -5954,3 +6000,84 @@ Stage 24 routed these investigation leads to their assigned later stages: - Retained decisions: `RET-059` through `RET-061`. - Open questions: none; remediation and dynamic-validation leads are routed above without changing later-stage scope. + +### Stage 26: Verify, Consolidate, And Triage Findings + +- Status: Complete. +- Scope reviewed: all 78 candidate findings, all 61 retained decisions, every + routed open question, finding-specific validation and test implications, the + stage-coverage table, and every risk-to-test coverage entry. +- Exclusions: Stage 25 remains pending because its interrupted results were not + promoted into audit evidence. No production code, test code, canonical + documentation, implementation priority, acceptance decision, or remediation + sequence was changed; those remain Stage 27 work. + +#### Final Disposition + +| Disposition | Count | Severity | Rationale | +| --- | ---: | --- | --- | +| Confirmed | 74 | 2 high, 43 medium, 29 low | Current assets, code paths, tests, graph/caller evidence, or focused probes support a distinct contract, safety, maintenance, or efficiency gap. Each entry names a corrective direction, test implications, and validation outcome. | +| Rejected as standalone | 4 | 4 low | The evidence is real, but a separate remediation item has insufficient cost-benefit because the work and validation are wholly owned by a broader confirmed root cause. Each rejected entry names that owner. | +| Deferred | 0 | — | No candidate lacks enough evidence to classify, and remediation deferral is a Stage 27 product-priority decision rather than a finding-confidence status. | + +All confidence ratings remain high after recheck. Severity remains calibrated +to plausible user, security, data-integrity, compatibility, or maintenance +impact rather than implementation cost: the two prompt defects remain high; +43 operationally consequential defects remain medium; structural, +documentation, test-cost, and dormant-surface issues remain low. Passing tests +do not lower the severity of missing boundary cases whose present behavior was +directly established. + +#### Consolidation And Recommendation Resolution + +| Root cause or sequence | Final ownership | +| --- | --- | +| Dormant compatibility and persistence | `AUD-072` owns the workflow-owner decision. `AUD-001`, `AUD-022`, and `AUD-032` are rejected only as standalone items and retain their evidence there. | +| Generated-text test ownership | `AUD-039` owns repeated day-style semantics, misplaced schema assertions, and duplicate render-output assertions. `AUD-063` is rejected as a separate slice of that same boundary. | +| Daypart identity and display | Establish one canonical key owner under `AUD-067`; use it to correct collision and planning behavior in `AUD-024`/`AUD-025`; keep Unicode-safe display formatting distinct under `AUD-073`. | +| Prepared metadata and render identity | Establish one prepared metadata authority under `AUD-069`, enforce agreement at context construction under `AUD-040`, then narrow unused render surfaces. | +| Weather collection efficiency | `AUD-065` may change acquisition scheduling only while preserving source-local outcomes and one deterministic ordered merge; it does not supersede source validation findings `AUD-011` through `AUD-015`. | +| Comparison recognition efficiency | `AUD-066` may reduce complete reads only while preserving early rejection and commit-time authorization owned by the publisher, including `AUD-053` through `AUD-056`. | +| Distributor diagnostics and body bounds | `AUD-049` and `AUD-050` remain requirements of the repository-owned adapter boundary. A future pinned-client capability may satisfy them, but dependency selection is an implementation choice and does not weaken the required bounded, redacted result. | +| Documentation repairs | `AUD-074`, `AUD-075`, `AUD-077`, and `AUD-078` must change with their executable owners; `AUD-076` removes duplicate completed roadmaps only after incoming links are checked. Current defects must not be documented as supported behavior. | + +#### High-Impact Recheck + +- Re-read the shared prompt against the prompt-input serializer. It still names + nonexistent `briefing.derived_daily_summary`, + `briefing.derived_daypart_summaries`, `briefing.precip_timing`, + `briefing.outdoor_windows`, and `briefing.metadata.alerts` paths while the + emitted package groups these values under `briefing.derived_summaries` and + alert data under applicable-risk products. `AUD-030` remains confirmed high. +- Rechecked the same prompt's claim that all retained hazard/risk products are + already location matched. Only point/polygon-specific products carry that + assurance; regional outlooks and discussions do not. `AUD-031` remains + confirmed high. +- Re-read diagnostic-body, prompt-debug, single-file publication, comparison + manifest/replacement/cleanup, and cancellation boundaries and reran their + focused packages. The medium security and data-integrity findings remain + distinct and reproducible from current branches or deterministic seams. + None is merely a duplicate of the high prompt-contract findings. +- Reconciled all historical open-question routes. Each terminates in a finding + or retained decision, and none presents unresolved high-impact evidence, so + no supplemental investigation stage is necessary. + +#### Commands And Evidence + +- Ran focused uncached tests for `internal/promptassets`, + `internal/promptinput`, `internal/adapters/promptkit`, `internal/fileutil`, + `internal/comparison`, and `internal/adapters/distributor`; all passed. +- Ran `GOWORK=off go test -count=1 ./...`, `GOWORK=off go vet ./...`, + `GOWORK=off go run ./cmd/weatherreporter --help`, and `git diff --check`; all + passed. +- Mechanically checked the final finding set: no `candidate` status remains; + all 74 confirmed findings contain recommendation, test-implication, and + validation fields; all four rejected findings contain an explicit + disposition and related consolidated owner; no finding is deferred. +- Reviewed every retained decision against the later-stage evidence. All 61 + remain valid with their stated reconsideration conditions; none conflicts + with the consolidated corrective directions. +- Findings: 74 confirmed; `AUD-001`, `AUD-022`, `AUD-032`, and `AUD-063` + rejected as standalone duplicates. +- Retained decisions: `RET-001` through `RET-061` revalidated. +- Open questions: none.