911 lines
46 KiB
Markdown
911 lines
46 KiB
Markdown
# Repository Audit Remediation Roadmap
|
|
|
|
Status: Ready for implementation.
|
|
|
|
## Purpose And Authority
|
|
|
|
This roadmap translates the confirmed findings in the
|
|
[repository audit ledger](audit.md) into dependency-ordered implementation
|
|
stages. The ledger owns discovery evidence and final finding disposition. This
|
|
document owns remediation scope, ordering, locked behavior, verification, and
|
|
completion state until the work is finished.
|
|
|
|
All 74 confirmed findings are accepted for remediation. None is priority-
|
|
deferred and none requires a separate product or architecture decision before
|
|
work can begin. Four rejected standalone findings remain consolidated into
|
|
their confirmed owners and are not separate work items.
|
|
|
|
This roadmap describes future work. Until an individual stage is implemented,
|
|
canonical current-state documentation and executable behavior remain
|
|
authoritative.
|
|
|
|
## Implementation Rules
|
|
|
|
Every stage must:
|
|
|
|
- read `docs/development.md`, all files under `docs/policy/`, this roadmap, and
|
|
the task-specific canonical documents identified below;
|
|
- implement only its listed findings and prerequisites;
|
|
- preserve the architecture policy's stateless pipeline, adapter boundaries,
|
|
curated prompt boundary, operator-owned outputs, comparison ordering, and
|
|
notification rules unless the stage explicitly corrects that contract;
|
|
- add durable tests at the narrowest stable boundary and avoid duplicating
|
|
behavior already owned elsewhere;
|
|
- update every listed canonical documentation owner in the same change as an
|
|
implemented contract change;
|
|
- use deterministic, offline, credential-free tests and synthetic fixtures;
|
|
- run `gofmt` on changed Go files, the stage's focused commands,
|
|
`GOWORK=off go test -count=1 ./...`, and `git diff --check`; and
|
|
- commit the completed stage separately when the implementing prompt requests
|
|
commits.
|
|
|
|
Stages affecting concurrent execution, cancellation, filesystem mutation, or
|
|
process-global state must also run the affected packages with `-race`. No stage
|
|
may weaken a safety invariant merely to make a test pass.
|
|
|
|
## Priority And Finding Allocation
|
|
|
|
Each confirmed finding appears exactly once below. Priority describes risk and
|
|
the default remediation order, not confidence; dependency prerequisites may
|
|
place a lower-priority consolidation mechanism before the P1 correction that
|
|
depends on it. Every listed finding has high confidence.
|
|
|
|
| Priority | Stages | Findings | Decision |
|
|
| --- | --- | --- | --- |
|
|
| P0: generated forecast integrity | 1 | `AUD-029`, `AUD-030`, `AUD-031`, `AUD-033` | Accepted now |
|
|
| P1: security, correctness, and data integrity | 2-14, 16-21, 24-37 | `AUD-002` through `AUD-021` excluding rejected `AUD-022`; `AUD-023` through `AUD-028`; `AUD-034` through `AUD-038`; `AUD-040` through `AUD-058`; `AUD-073`, `AUD-074`, `AUD-077`, and `AUD-078` | Accepted now |
|
|
| P2: deterministic test and operational quality | 38-43 | `AUD-059` through `AUD-062`, `AUD-064`, `AUD-065`, and `AUD-066` | Accepted now |
|
|
| P3: behavior-preserving consolidation and cleanup | 15, 22-23, 44-52 | `AUD-039`, `AUD-067` through `AUD-072` | Accepted now; Stages 15 and 22-23 run early because P1 corrections depend on them |
|
|
| P4: documentation lifecycle and audit retirement | 53-56 | `AUD-075` and `AUD-076`; final audit-record retirement | Accepted now |
|
|
|
|
Rejected `AUD-001`, `AUD-022`, and `AUD-032` are represented only through
|
|
`AUD-072`; rejected `AUD-063` is represented only through `AUD-039`.
|
|
|
|
## Remediation Stages
|
|
|
|
### Stage 1: Correct The Curated Prompt Package Contract
|
|
|
|
- Findings: `AUD-029`, `AUD-030`, `AUD-031`, `AUD-033`.
|
|
- Affected areas: `internal/promptinput`, shared embedded prompt assets, and
|
|
focused prompt-input/prompt-asset tests.
|
|
- Work: remove raw transport-shaped warning details from provider input; make
|
|
shared prompt paths match serialized YAML; describe regional versus point-
|
|
matched hazard products accurately; and cover stanza serialization failure.
|
|
- Locked behavior: deterministic category/stanza order, exact prompt identity,
|
|
safe normal diagnostics, and byte-stable valid YAML remain unchanged.
|
|
- Documentation owners: `docs/internal/prompt-input.md` and
|
|
`docs/integrations/promptkit.md` if their implemented contract changes.
|
|
- Exit commands: focused tests for `./internal/promptinput` and
|
|
`./internal/promptassets`, then the standard repository commands.
|
|
|
|
### Stage 2: Make Configuration Keys And Overrides Explicit
|
|
|
|
- Findings: `AUD-004`, `AUD-006`, `AUD-078`.
|
|
- Affected areas: `internal/config`, report-key lookup, timezone parsing,
|
|
maintained examples, and configuration tests.
|
|
- Work: reject unsupported missing-source keys; make programmatic report
|
|
overrides obey the same presence semantics as loaded configuration; and
|
|
document accepted report-key normalization and numeric-offset bounds.
|
|
- Locked behavior: file/CLI precedence, inactive-integration policy, exact
|
|
command-name lookup, and secret redaction remain unchanged.
|
|
- Documentation owners: `docs/config.md` and maintained examples only where
|
|
executable behavior requires them.
|
|
- Exit commands: focused config and CLI tests, followed by the standard
|
|
repository commands.
|
|
|
|
### Stage 3: Make Secret Loading Atomic
|
|
|
|
- Findings: `AUD-007`.
|
|
- Affected areas: configuration loading, secret-directory application, load
|
|
failure state, and focused configuration tests.
|
|
- Work: stage secret values and apply them to the returned configuration only
|
|
after the complete load and validation sequence succeeds.
|
|
- Locked behavior: secret precedence, configured secret-directory discovery,
|
|
environment independence, actionable errors, and redaction remain unchanged.
|
|
- Documentation owners: `docs/config.md` only if the observable load contract
|
|
needs clarification.
|
|
- Exit commands: focused config tests plus
|
|
`GOWORK=off go test -race -count=1 ./internal/config`, followed by the
|
|
standard repository commands.
|
|
|
|
### Stage 4: Require Complete Single-Report Notification Identity
|
|
|
|
- Findings: `AUD-005`.
|
|
- Affected areas: Distributor notification configuration, bundle-ID rendering,
|
|
and focused config/app tests.
|
|
- Work: reject enabled single-report notification configurations that can
|
|
produce blank required identity fields before report work begins.
|
|
- Locked behavior: inactive notification settings remain optional; configured
|
|
templates and publication-before-notification ordering remain intact.
|
|
- Documentation owners: `docs/config.md`, `docs/operations.md`, and Distributor
|
|
integration docs if accepted values or failures change.
|
|
- Exit commands: focused config and app notification tests, then the standard
|
|
repository commands.
|
|
|
|
### Stage 5: Propagate Process Interrupt Cancellation
|
|
|
|
- Findings: `AUD-008`.
|
|
- Affected areas: `cmd/weatherreporter`, action contexts, CLI wiring, and
|
|
interrupt/cancellation tests.
|
|
- Work: convert operating-system interrupts into action-context cancellation
|
|
and verify active generation, batch, and comparison workflows observe it.
|
|
- Locked behavior: command/flag ownership, structured summary shapes, stream
|
|
separation, and one executor per action remain unchanged.
|
|
- Documentation owners: `docs/cli.md`, `docs/operations.md`, and
|
|
`docs/internal/cli.md` if signal behavior needs clarification.
|
|
- Exit commands: `GOWORK=off go test -race -count=1 ./internal/cli
|
|
./internal/app ./cmd/weatherreporter`, then the standard repository commands.
|
|
|
|
### Stage 6: Correct CLI Preflight, Coverage, And Visible Contracts
|
|
|
|
- Findings: `AUD-009`, `AUD-010`, `AUD-074`.
|
|
- Affected areas: `internal/cli`, executor construction, assembled CLI tests,
|
|
help text, and CLI documentation.
|
|
- Work: validate report dates before executor construction; add representative
|
|
generate and batch result/exit tests; and align help/internal guidance with
|
|
quiet, date, and comparison behavior.
|
|
- Locked behavior: command/flag ownership, structured summary shapes, stream
|
|
separation, cancellation from Stage 5, and one executor per action remain
|
|
unchanged.
|
|
- Documentation owners: `docs/cli.md` and `docs/internal/cli.md`.
|
|
- Exit commands: focused CLI/app tests, both root and comparison help commands,
|
|
then the standard repository commands.
|
|
|
|
### Stage 7: Validate Weather API Endpoints And Retry Classification
|
|
|
|
- Findings: `AUD-011`, `AUD-015`.
|
|
- Affected areas: Weather API configuration and adapter construction, warmup
|
|
retry classification, local HTTP fixtures, and focused tests.
|
|
- Work: accept only supported endpoint forms and retry warmup only for
|
|
transient failures.
|
|
- Locked behavior: all eight source contracts, checked-empty optional products,
|
|
cancellation, provenance, and offline testing remain intact.
|
|
- Documentation owners: `docs/config.md`, `docs/integrations/weatherapi.md`,
|
|
and `docs/internal/collect.md` as applicable.
|
|
- Exit commands: focused configuration, adapter, and collection tests, then the
|
|
standard repository commands.
|
|
|
|
### Stage 8: Bound And Redact Weather API Diagnostics
|
|
|
|
- Findings: `AUD-012`, `AUD-013`.
|
|
- Affected areas: Weather API response reading, non-success error projection,
|
|
size limits, local HTTP fixtures, and focused adapter tests.
|
|
- Work: replace upstream response text with bounded safe diagnostics and reject
|
|
rather than silently truncate oversized bodies.
|
|
- Locked behavior: HTTP status classification, source-local error context,
|
|
cancellation, and offline tests remain intact.
|
|
- Documentation owners: `docs/integrations/weatherapi.md` and
|
|
`docs/internal/collect.md` if observable limits or diagnostics change.
|
|
- Exit commands: focused boundary-size and malicious-response adapter tests,
|
|
then the standard repository commands.
|
|
|
|
### Stage 9: Require Usable Hourly Period Bounds
|
|
|
|
- Findings: `AUD-014`.
|
|
- Affected areas: Weather API hourly decoding, normalized hourly data,
|
|
required-source validation, fixtures, and focused tests.
|
|
- Work: reject required hourly products whose periods do not contain usable
|
|
time bounds before they enter collection and derivation.
|
|
- Locked behavior: required/optional source policy, source provenance,
|
|
chronological selection, and valid hourly fixtures remain unchanged.
|
|
- Documentation owners: `docs/integrations/weatherapi.md`,
|
|
`docs/internal/weather-data.md`, and `docs/internal/collect.md`.
|
|
- Exit commands: focused weather-data, adapter, and collection tests, then the
|
|
standard repository commands.
|
|
|
|
### Stage 10: Correct Civil-Time Windows And Daily Run Identity
|
|
|
|
- Findings: `AUD-002`, `AUD-003`.
|
|
- Affected areas: `internal/timeutil`, Daily report identity, DST and run-ID
|
|
tests, and report-registry documentation.
|
|
- Work: construct configured clocks as local civil times across both DST
|
|
transitions and add durable protection for Daily run-ID uniqueness.
|
|
- Locked behavior: half-open selection, civil-day report periods, rolling
|
|
Hourly elapsed time, and source-period identity remain unchanged.
|
|
- Documentation owners: `docs/internal/report-registry.md`.
|
|
- Exit commands: focused time/report tests with both DST transitions, then the
|
|
standard repository commands.
|
|
|
|
### Stage 11: Preserve Units And Overnight Alert Coverage
|
|
|
|
- Findings: `AUD-016`, `AUD-017`.
|
|
- Affected areas: `internal/forecast`, `internal/facts`, metric fallback
|
|
values, overnight dayparts, alerts, and focused tests.
|
|
- Work: preserve units in fallback values and include alerts over the complete
|
|
overnight interval.
|
|
- Locked behavior: half-open overlap semantics, chronological ordering, source
|
|
periods, and valid US-customary results remain unchanged.
|
|
- Documentation owners: `docs/internal/forecast-derivation.md` and
|
|
`docs/internal/facts.md`.
|
|
- Exit commands: focused forecast/facts tests with metric and overnight cases,
|
|
then the standard repository commands.
|
|
|
|
### Stage 12: Validate Precipitation And Ice Classification
|
|
|
|
- Findings: `AUD-018`, `AUD-019`.
|
|
- Affected areas: precipitation-domain validation, weather-text
|
|
classification, derived summaries, and focused forecast/facts tests.
|
|
- Work: reject precipitation probabilities outside the percentage domain and
|
|
classify ordinary icy wording consistently.
|
|
- Locked behavior: valid percentage handling, summary ordering, and existing
|
|
weather-condition categories remain unchanged.
|
|
- Documentation owners: `docs/internal/forecast-derivation.md` and
|
|
`docs/internal/facts.md`.
|
|
- Exit commands: focused forecast/facts boundary tests, then the standard
|
|
repository commands.
|
|
|
|
### Stage 13: Correct Source-Facing Briefing Module Semantics
|
|
|
|
- Findings: `AUD-020`, `AUD-021`.
|
|
- Affected areas: briefing module option validation, weather-story construction,
|
|
module registry tests, and normalized source fixtures.
|
|
- Work: make accepted AFD option shapes constructible and omit semantically
|
|
empty weather stories instead of publishing false availability.
|
|
- Locked behavior: report support, default compositions, checked-empty alerts,
|
|
and ordered module snapshots remain unchanged.
|
|
- Documentation owners: `docs/internal/module.md` and
|
|
`docs/internal/briefing.md`.
|
|
- Exit commands: focused briefing/module tests, then the standard repository
|
|
commands.
|
|
|
|
### Stage 14: Correct Derived Briefing Language And Ranking
|
|
|
|
- Findings: `AUD-023`, `AUD-026`, `AUD-027`.
|
|
- Affected areas: derived daily summaries, outdoor-window scoring, temperature
|
|
band wording, and briefing tests.
|
|
- Work: label apparent temperature accurately; include snow, ice, and fog in
|
|
outdoor-window ranking; and preserve negative-zero temperature meaning.
|
|
- Locked behavior: deterministic ranking, Today-only planning scope, and
|
|
existing module/schema identities remain unchanged.
|
|
- Documentation owners: `docs/internal/briefing.md` and prompt-facing field
|
|
documentation if names or meaning change.
|
|
- Exit commands: focused briefing tests with metric, subzero, and hazard cases,
|
|
then the standard repository commands.
|
|
|
|
### Stage 15: Establish One Daypart Canonicalization Mechanism
|
|
|
|
- Findings: `AUD-067`.
|
|
- Affected areas: duplicated canonical-key helpers in briefing and
|
|
generated-text packages plus their behavior tests.
|
|
- Work: establish one domain-owned canonical key contract and route both
|
|
current consumers through it without changing accepted ASCII behavior.
|
|
- Locked behavior: display labels, report-specific semantic roles, ordering,
|
|
and current valid output remain unchanged.
|
|
- Documentation owners: focused internal briefing/generated-text docs only if
|
|
ownership needs explanation.
|
|
- Exit commands: focused briefing and generated-text tests, then the standard
|
|
repository commands.
|
|
|
|
### Stage 16: Correct Daypart Identity, Collision, And Display Behavior
|
|
|
|
- Findings: `AUD-024`, `AUD-025`, `AUD-073`.
|
|
- Affected areas: derived daypart summaries, planning builders, display
|
|
capitalization, configuration fixtures, and rendering tests.
|
|
- Work: reject canonical-key collisions; use configured identities consistently
|
|
across planning; and make non-ASCII display capitalization rune-safe.
|
|
- Locked behavior: Stage 15's canonical identity remains separate from display
|
|
text; stable ordering and default dayparts remain unchanged.
|
|
- Documentation owners: `docs/config.md`, `docs/internal/briefing.md`, and
|
|
generated-text/template docs if visible labels change.
|
|
- Exit commands: focused config/briefing/generated-text/reporttemplate tests,
|
|
then the standard repository commands.
|
|
|
|
### Stage 17: Refresh The Official SPC Definition Asset
|
|
|
|
- Findings: `AUD-028`.
|
|
- Affected areas: embedded SPC category definitions, source attribution, and
|
|
risk-digest tests.
|
|
- Work: reconcile descriptions with the current authoritative SPC table and
|
|
record a durable source/review mechanism without changing risk thresholds
|
|
accidentally.
|
|
- Locked behavior: deterministic category ordering, threshold selection, and
|
|
overlap logic remain unchanged unless current official semantics require an
|
|
explicit reviewed correction.
|
|
- Documentation owners: `docs/internal/briefing.md` or another single
|
|
canonical maintainer owner for the external definition source.
|
|
- Exit commands: focused briefing asset/risk tests, then the standard
|
|
repository commands.
|
|
|
|
### Stage 18: Harden Prompt-Debug Redaction
|
|
|
|
- Findings: `AUD-034`.
|
|
- Affected areas: `internal/promptdebug`, Promptkit debug callbacks, endpoint
|
|
redaction, and adversarial content tests.
|
|
- Work: redact common credential aliases and URL credential forms from every
|
|
explicit debug artifact and error projection.
|
|
- Locked behavior: debug remains explicit opt-in with `0700` directories,
|
|
`0600` files, deterministic references, and no sensitive normal output.
|
|
- Documentation owners: `docs/operations.md` and
|
|
`docs/integrations/promptkit.md`.
|
|
- Exit commands: focused promptdebug/Promptkit redaction tests, then the
|
|
standard repository commands.
|
|
|
|
### Stage 19: Make Prompt-Debug Filesystem Traversal Race-Resistant
|
|
|
|
- Findings: `AUD-035`.
|
|
- Affected areas: `internal/promptdebug`, secure directory and file creation,
|
|
Promptkit debug callbacks, and adversarial filesystem tests.
|
|
- Work: replace pathname check/use gaps with a race-resistant secure traversal
|
|
and creation strategy while preserving atomic replacement and actionable
|
|
failures.
|
|
- Locked behavior: Stage 18 redaction, explicit opt-in, `0700` directories,
|
|
`0600` files, deterministic references, containment, and ordinary concurrent
|
|
execution remain unchanged.
|
|
- Documentation owners: `docs/operations.md` and
|
|
`docs/integrations/promptkit.md`.
|
|
- Exit commands: focused promptdebug/Promptkit tests plus
|
|
`GOWORK=off go test -race -count=1 ./internal/promptdebug
|
|
./internal/adapters/promptkit ./internal/app`, then standard commands.
|
|
|
|
### Stage 20: Enforce Generated-Text Identity And Shape
|
|
|
|
- Findings: `AUD-036`, `AUD-037`.
|
|
- Affected areas: generated-text catalog, decoders, schemas, typed validators,
|
|
and focused tests.
|
|
- Work: require report-specific schema/template pairs; reject case-variant
|
|
properties that schemas reject.
|
|
- Locked behavior: typed normalization, exact registered identities, schema
|
|
copy isolation, and valid generated content remain unchanged.
|
|
- Documentation owners: `docs/internal/generatedtext.md` and template docs.
|
|
- Exit commands: focused generated-text and promptassets tests, then the
|
|
standard repository commands.
|
|
|
|
### Stage 21: Bound Generated Content And Diagnostics
|
|
|
|
- Findings: `AUD-038`.
|
|
- Affected areas: generated-text decoders and typed validators, schemas,
|
|
Promptkit result handling, safe error projection, and boundary tests.
|
|
- Work: bound prose, arrays, total generated content, and diagnostic context
|
|
before allocation or normal error projection.
|
|
- Locked behavior: Stage 20 identity/shape enforcement, typed normalization,
|
|
valid generated content, and content-safe normal summaries remain unchanged.
|
|
- Documentation owners: `docs/internal/generatedtext.md`, template docs, and
|
|
Promptkit integration limits where externally relevant.
|
|
- Exit commands: focused generated-text/promptassets/app tests at and around
|
|
every limit, then the standard repository commands.
|
|
|
|
### Stage 22: Establish The Prepared Metadata Authority
|
|
|
|
- Findings: `AUD-069`.
|
|
- Affected areas: briefing metadata construction, prepared reports, identity
|
|
and timing values, and focused app/briefing tests.
|
|
- Work: define one prepared identity/timing authority, populate it at the
|
|
preparation boundary, and lock its equivalence to current valid output.
|
|
- Locked behavior: prompt and output bytes for valid fixtures, immutable
|
|
prepared inputs, and module ordering remain unchanged.
|
|
- Documentation owners: `docs/internal/prepared-report.md`,
|
|
`docs/internal/briefing.md`.
|
|
- Exit commands: focused briefing and app tests, then the standard repository
|
|
commands.
|
|
|
|
### Stage 23: Migrate Prepared Metadata Projections
|
|
|
|
- Findings: none; this completes the remediation begun in Stage 22.
|
|
- Affected areas: prompt metadata projection, render-context inputs, superseded
|
|
parallel fields, and focused prompt/render tests.
|
|
- Work: route prompt and render projections through Stage 22's authority, then
|
|
remove or narrow superseded fields without changing serialized YAML or
|
|
rendered Markdown.
|
|
- Locked behavior: Stage 22's authority, prompt and output bytes for valid
|
|
fixtures, immutable prepared inputs, and module ordering remain unchanged.
|
|
- Documentation owners: `docs/internal/prepared-report.md`,
|
|
`docs/internal/briefing.md`, and `docs/internal/prompt-input.md`.
|
|
- Exit commands: focused briefing/app/promptinput/generatedtext tests, then the
|
|
standard repository commands.
|
|
|
|
### Stage 24: Enforce Render Identity And Empty-Section Behavior
|
|
|
|
- Findings: `AUD-040`, `AUD-042`.
|
|
- Affected areas: render-context builders, Today templates/partials, and
|
|
focused context/rendering tests.
|
|
- Work: reject conflicting report identities and suppress or replace a Today
|
|
daypart section that has no rows or fallback.
|
|
- Locked behavior: repository templates remain Markdown owners, deterministic
|
|
facts remain authoritative, and normal section order remains unchanged.
|
|
- Documentation owners: `docs/templates.md`,
|
|
`docs/internal/generatedtext.md`, and `docs/internal/reporttemplate.md`.
|
|
- Exit commands: focused generated-text/reporttemplate/app tests, then the
|
|
standard repository commands.
|
|
|
|
### Stage 25: Prevent Generated Prose From Impersonating Markdown Structure
|
|
|
|
- Findings: `AUD-041`.
|
|
- Affected areas: generated prose insertion, Markdown templates/partials,
|
|
renderer policy, and adversarial rendering tests.
|
|
- Work: define and enforce the smallest content-handling rule that prevents
|
|
generated prose from creating structure that impersonates deterministic
|
|
report sections.
|
|
- Locked behavior: repository templates remain Markdown owners, deterministic
|
|
facts remain authoritative, ordinary generated prose remains readable, and
|
|
normal section order remains unchanged.
|
|
- Documentation owners: `docs/templates.md`,
|
|
`docs/internal/generatedtext.md`, and `docs/internal/reporttemplate.md`.
|
|
- Exit commands: focused generated-text/reporttemplate/app tests with
|
|
adversarial headings and related Markdown constructs, then the standard
|
|
repository commands.
|
|
|
|
### Stage 26: Move Prompt Compatibility Checks Before Collection
|
|
|
|
- Findings: `AUD-043`.
|
|
- Affected areas: application prompt inspection and preparation,
|
|
generated-text catalog preflight, collection ordering, and app tests.
|
|
- Work: validate catalog compatibility before collection or other expensive
|
|
report work begins.
|
|
- Locked behavior: one inspection/preparation, profile precedence, immutable
|
|
execution copies, and partial execution result ownership remain unchanged.
|
|
- Documentation owners: `docs/internal/prepared-report.md`,
|
|
`docs/internal/app-orchestration.md`, and Promptkit integration docs.
|
|
- Exit commands: focused app and generatedtext tests proving failure ordering,
|
|
then the standard repository commands.
|
|
|
|
### Stage 27: Reconcile Prompt Execution Provenance
|
|
|
|
- Findings: `AUD-044`.
|
|
- Affected areas: prompt inspection, prepared execution values, callbacks,
|
|
completed execution results, schema validation, and app tests.
|
|
- Work: reconcile inspected, prepared, callback, completed, and schema
|
|
identities before accepting generated output.
|
|
- Locked behavior: Stage 26 preflight ordering, one inspection/preparation,
|
|
profile precedence, immutable execution copies, and partial result ownership
|
|
remain unchanged.
|
|
- Documentation owners: `docs/internal/prepared-report.md`,
|
|
`docs/internal/app-orchestration.md`, and Promptkit integration docs.
|
|
- Exit commands: focused app/promptexec/generatedtext tests with mismatched
|
|
provenance at each boundary, then the standard repository commands.
|
|
|
|
### Stage 28: Preflight Single-Report Temporary Names
|
|
|
|
- Findings: `AUD-046`.
|
|
- Affected areas: app output planning, bounded temporary naming, destination
|
|
validation, directory creation, and focused filesystem tests.
|
|
- Work: detect temporary-name and basename limits during preflight without
|
|
leaving newly created directories after failure.
|
|
- Locked behavior: destination selection, same-directory atomic visibility,
|
|
final filenames, and existing regular-file preservation remain unchanged.
|
|
- Documentation owners: `docs/operations.md` and app orchestration internals if
|
|
preflight behavior needs clarification.
|
|
- Exit commands: focused fileutil/app/CLI long-name tests, then the standard
|
|
repository commands.
|
|
|
|
### Stage 29: Make Single-Report Publication Type-Safe And Cancelable
|
|
|
|
- Findings: `AUD-045`, `AUD-047`.
|
|
- Affected areas: `internal/fileutil`, app output planning/publication,
|
|
destination error projection, and filesystem tests.
|
|
- Work: reject non-regular final destinations; use bounded temporary naming
|
|
from Stage 28; and check cancellation at the rename linearization point.
|
|
- Locked behavior: same-directory atomic visibility, preservation of prior
|
|
regular files, restrictive new-file mode, truthful committed paths, and
|
|
notification-after-publication remain unchanged.
|
|
- Documentation owners: `docs/operations.md`, architecture policy if an
|
|
invariant needs clarification, and app orchestration internals.
|
|
- Exit commands: focused fileutil/app/CLI filesystem tests plus
|
|
`GOWORK=off go test -race -count=1 ./internal/fileutil ./internal/app
|
|
./internal/cli`, then standard commands.
|
|
|
|
### Stage 30: Validate Distributor Endpoints Before Publication
|
|
|
|
- Findings: `AUD-048`.
|
|
- Affected areas: Distributor configuration validation, app preflight,
|
|
endpoint construction, and focused config/app tests.
|
|
- Work: reject unsupported endpoint forms before report publication.
|
|
- Locked behavior: exactly-once upload/status mapping, published-file source
|
|
selection, token redaction, and dependency types remaining adapter-local.
|
|
- Documentation owners: `docs/config.md`, `docs/operations.md`, and Distributor
|
|
integration docs.
|
|
- Exit commands: focused config and app preflight tests, then the standard
|
|
repository commands.
|
|
|
|
### Stage 31: Bound Distributor Diagnostics And Exercise The HTTP Boundary
|
|
|
|
- Findings: `AUD-049`, `AUD-050`, `AUD-052`.
|
|
- Affected areas: Distributor adapter, pinned client interaction, response
|
|
reading and classification, local HTTP tests, and safe batch diagnostics.
|
|
- Work: bound response reads; redact or classify remote text before normal
|
|
results; and exercise the real production HTTP boundary with a local server.
|
|
- Locked behavior: Stage 30 endpoint validation, exactly-once upload/status
|
|
mapping, published-file source selection, token redaction, and adapter-local
|
|
dependency types remain unchanged.
|
|
- Documentation owners: `docs/operations.md`,
|
|
`docs/internal/distributor-adapter.md`, and Distributor integration docs.
|
|
- Exit commands: focused distributor/app tests including oversized and
|
|
malicious response bodies, then the standard repository commands.
|
|
|
|
### Stage 32: Preserve Batch Cancellation As A Distinct Outcome
|
|
|
|
- Findings: `AUD-051`.
|
|
- Affected areas: batch orchestration, result/error types, CLI projection, and
|
|
cancellation tests.
|
|
- Work: stop starting later reports after cancellation and preserve
|
|
cancellation separately from independent report failures and notification
|
|
state.
|
|
- Locked behavior: collect once, deterministic planned order, continuation
|
|
after non-cancellation failures, report-only counters, and all-success
|
|
notification gating remain unchanged.
|
|
- Documentation owners: `docs/cli.md`, `docs/operations.md`, and
|
|
`docs/internal/app-orchestration.md`.
|
|
- Exit commands: focused app/CLI tests plus
|
|
`GOWORK=off go test -race -count=1 ./internal/app ./internal/cli`, then
|
|
standard commands.
|
|
|
|
### Stage 33: Tighten Comparison Manifest Compatibility
|
|
|
|
- Findings: `AUD-053`, `AUD-054`.
|
|
- Affected areas: comparison JSON decoding, manifest/logical-bundle validation,
|
|
filename helpers, and compatibility tests.
|
|
- Work: reject duplicate and case-variant fields and require each successful
|
|
report path to equal the canonical ordinal/profile filename.
|
|
- Locked behavior: current schema version, deterministic encoding/hashing,
|
|
flat exact file set, ordered profiles, and bounded recognition errors remain.
|
|
- Documentation owners: `docs/integrations/comparison-bundle.md` and
|
|
`docs/internal/comparison-publication.md`.
|
|
- Exit commands: focused comparison compatibility tests, then the standard
|
|
repository commands.
|
|
|
|
### Stage 34: Preflight Comparison Sibling Names
|
|
|
|
- Findings: `AUD-057`.
|
|
- Affected areas: comparison destination planning, staging and backup sibling
|
|
naming, parent directory creation, and focused filesystem tests.
|
|
- Work: validate derived sibling-name constraints during preflight and fail
|
|
without leaving residual directories.
|
|
- Locked behavior: exact target selection, sibling staging, broad-target
|
|
rejection, and valid destination names remain unchanged.
|
|
- Documentation owners: comparison publication internals and operations if
|
|
preflight behavior needs clarification.
|
|
- Exit commands: focused comparison/app long-name tests, then the standard
|
|
repository commands.
|
|
|
|
### Stage 35: Honor Cancellation At Comparison Replacement Commit
|
|
|
|
- Findings: `AUD-055`.
|
|
- Affected areas: comparison replacement transaction, cancellation
|
|
linearization, rollback, and deterministic filesystem tests.
|
|
- Work: honor cancellation after moving the prior bundle but before installing
|
|
the replacement, restoring or retaining the prior bundle according to the
|
|
transaction's recovery rules.
|
|
- Locked behavior: Stage 34 preflight, post-move authorization, no forced
|
|
destructive cleanup, rollback, and committed-new-bundle truth remain.
|
|
- Documentation owners: comparison bundle/publication docs and operations.
|
|
- Exit commands: focused comparison/app cancellation tests plus
|
|
`GOWORK=off go test -race -count=1 ./internal/comparison ./internal/app`,
|
|
then the standard repository commands.
|
|
|
|
### Stage 36: Represent Comparison Backup Recovery Truthfully
|
|
|
|
- Findings: `AUD-056`.
|
|
- Affected areas: comparison backup cleanup, publication result/error state,
|
|
app/CLI recovery projection, and deterministic filesystem tests.
|
|
- Work: distinguish a complete retained recovery bundle from a partially
|
|
removed backup and report the actual recoverable state without deleting the
|
|
committed new bundle.
|
|
- Locked behavior: post-move authorization, rollback, no forced destructive
|
|
cleanup, Stage 35 cancellation behavior, committed-new-bundle truth, and
|
|
actionable recovery paths remain.
|
|
- Documentation owners: comparison bundle/publication docs, operations, and
|
|
CLI result docs where state representation changes.
|
|
- Exit commands: focused comparison/app/CLI tests plus
|
|
`GOWORK=off go test -race -count=1 ./internal/comparison ./internal/app
|
|
./internal/cli`, then standard commands.
|
|
|
|
### Stage 37: State Executor Concurrency And Preserve Profile Failures
|
|
|
|
- Findings: `AUD-058`, `AUD-077`.
|
|
- Affected areas: `promptexec.Executor` contract, comparison execution/result
|
|
aggregation, Promptkit adapter, app fakes, and CLI tests.
|
|
- Work: document and test concurrent-call substitutability and preserve
|
|
already-completed profile failures when later command cancellation occurs.
|
|
- Locked behavior: one shared executor, one goroutine per explicit profile,
|
|
provider-owned capacity, joined workers, selection ordering, and no
|
|
Distributor notification remain unchanged.
|
|
- Documentation owners: Promptkit integration and comparison execution/app
|
|
orchestration internals.
|
|
- Exit commands: focused promptexec/Promptkit/app/CLI tests plus
|
|
`GOWORK=off go test -race -count=1 ./internal/adapters/promptkit
|
|
./internal/app ./internal/cli`, then standard commands.
|
|
|
|
### Stage 38: Make Tests Independent Of Ambient Host State
|
|
|
|
- Findings: `AUD-059`, `AUD-060`.
|
|
- Affected areas: Promptkit credential tests and symlink tests in app,
|
|
promptdebug, and comparison packages.
|
|
- Work: explicitly control the credential environment and treat inability to
|
|
create symlinks as a tested capability prerequisite rather than product
|
|
failure.
|
|
- Locked behavior: real supported-host symlink safety assertions and missing-
|
|
credential behavior remain fully protected.
|
|
- Documentation owners: testing policy only if supported-platform policy is
|
|
deliberately changed; normally none.
|
|
- Exit commands: focused packages under scrubbed and ordinary environments,
|
|
race-enabled focused tests, then standard commands.
|
|
|
|
### Stage 39: Remove Redundant Assertions And Production Test Waits
|
|
|
|
- Findings: `AUD-061`, `AUD-062`.
|
|
- Affected areas: briefing SPC tests, collection wrapper tests, Distributor
|
|
polling tests, and narrow timing seams.
|
|
- Work: remove the private-constant assertion while retaining observable risk
|
|
behavior; inject only the wait controls necessary to avoid production delays
|
|
in deterministic tests.
|
|
- Locked behavior: production retry/poll intervals and observable SPC policy
|
|
remain unchanged.
|
|
- Documentation owners: none unless a contributor-facing test seam warrants a
|
|
focused internal note.
|
|
- Exit commands: focused briefing/collect/distributor tests with repeated runs,
|
|
then the standard repository commands.
|
|
|
|
### Stage 40: Make Comparison Test Failure Cleanup Total
|
|
|
|
- Findings: `AUD-064`.
|
|
- Affected areas: comparison execution test barriers and worker cleanup in
|
|
`internal/app` tests.
|
|
- Work: release and join workers on timeout, early completion, duplicate start,
|
|
and every diagnostic exit without weakening liveness detection.
|
|
- Locked behavior: production comparison scheduling and five-second deadlock
|
|
diagnostics remain unchanged.
|
|
- Documentation owners: none.
|
|
- Exit commands: repeat focused comparison-execution tests and run them with
|
|
`-race`, then the standard repository commands.
|
|
|
|
### Stage 41: Remove The Redundant Weather Warmup Fetch
|
|
|
|
- Findings: `AUD-065`.
|
|
- Affected areas: Weather API warmup and current-conditions acquisition,
|
|
retry semantics from Stage 7, request counts, and adapter/collection tests.
|
|
- Work: reuse the successful warmup response or remove the redundant warmup so
|
|
current conditions are not fetched and decoded twice.
|
|
- Locked behavior: source-local validation/errors, exact source order,
|
|
required/optional policy, Stage 7 retry policy, and context cancellation
|
|
remain authoritative.
|
|
- Documentation owners: Weather API integration and collection internals if
|
|
operational request behavior changes materially.
|
|
- Exit commands: focused request-count and retry tests, then the standard
|
|
repository commands.
|
|
|
|
### Stage 42: Acquire Independent Weather Sources Concurrently
|
|
|
|
- Findings: none; this completes the efficiency remediation begun in Stage 41.
|
|
- Affected areas: Weather API bundle acquisition, request-result aggregation,
|
|
provenance ordering, cancellation, and adapter/collection tests.
|
|
- Work: execute independent source requests concurrently and merge their
|
|
results in one deterministic source order.
|
|
- Locked behavior: Stage 41 current-response handling, source-local
|
|
validation/errors, exact source order, required/optional policy, Stage 7
|
|
retry policy, and context cancellation remain authoritative.
|
|
- Documentation owners: Weather API integration and collection internals if
|
|
operational request behavior changes materially.
|
|
- Exit commands: focused latency, deterministic-order, failure, and
|
|
cancellation tests plus
|
|
`GOWORK=off go test -race -count=1 ./internal/adapters/weatherapi
|
|
./internal/collect`, then standard commands.
|
|
|
|
### Stage 43: Eliminate Repeated Comparison Bundle Reads
|
|
|
|
- Findings: `AUD-066`.
|
|
- Affected areas: comparison recognition/planning/publication and app
|
|
comparison preflight.
|
|
- Work: pass or cache only the recognition evidence needed to avoid four full
|
|
reads while retaining reauthorization at every mutation boundary.
|
|
- Locked behavior: early rejection, exact file/type validation, post-move
|
|
authorization, deterministic hashes, and concurrent destination safety after
|
|
Stages 34-36 remain unchanged.
|
|
- Documentation owners: comparison publication internals if ownership or
|
|
transaction phases change.
|
|
- Exit commands: focused read-count and adversarial replacement tests plus
|
|
`GOWORK=off go test -race -count=1 ./internal/comparison ./internal/app`, then
|
|
standard commands.
|
|
|
|
### Stage 44: Consolidate Distributor Template Parsing
|
|
|
|
- Findings: `AUD-068`.
|
|
- Affected areas: single and batch notification template rendering and config
|
|
tests.
|
|
- Work: extract one private grammar/parser with typed callbacks while
|
|
preserving each template family's variable allowlist and error context.
|
|
- Locked behavior: accepted syntax, rejected malformed forms, exact rendering,
|
|
and single-versus-batch policy remain unchanged.
|
|
- Documentation owners: none unless the user-visible grammar changes, which is
|
|
outside this behavior-preserving stage.
|
|
- Exit commands: focused config tests, then the standard repository commands.
|
|
|
|
### Stage 45: Define One Fact Requirement Vocabulary
|
|
|
|
- Findings: `AUD-070`.
|
|
- Affected areas: module requirement vocabulary, current briefing definitions,
|
|
identity/category metadata, and focused module/briefing tests.
|
|
- Work: define each requirement's identity and category once, preserve each
|
|
module's explicit requirement list, and lock equivalence with current valid
|
|
compositions.
|
|
- Locked behavior: all current compositions, supported reports, availability,
|
|
and diagnostic identity remain byte-for-byte or semantically unchanged.
|
|
- Documentation owners: module and briefing internals if ownership changes.
|
|
- Exit commands: focused module and briefing catalog tests, then the standard
|
|
repository commands.
|
|
|
|
### Stage 46: Migrate Fact Availability And Constructor Validation
|
|
|
|
- Findings: none; this completes the remediation begun in Stage 45.
|
|
- Affected areas: availability predicates, briefing constructors, legacy
|
|
switches, configuration validation, and focused tests.
|
|
- Work: route availability and constructor validation through Stage 45's
|
|
requirement vocabulary and remove superseded policy implementations.
|
|
- Locked behavior: all current compositions, supported reports, missing-data
|
|
policy, availability, and diagnostic identity remain unchanged.
|
|
- Documentation owners: module and briefing internals if ownership changes.
|
|
- Exit commands: focused module/briefing/config tests, then the standard
|
|
repository commands.
|
|
|
|
### Stage 47: Consolidate CLI Report-Date Policy
|
|
|
|
- Findings: `AUD-071`.
|
|
- Affected areas: generate/comparison flag registration and date resolution,
|
|
CLI parser/action tests, and private CLI descriptors.
|
|
- Work: establish one private report-date policy/resolver used by both actions
|
|
after Stage 6 has locked corrected behavior.
|
|
- Locked behavior: accepted flags, required/default dates, action-specific
|
|
errors, and request types remain unchanged.
|
|
- Documentation owners: none unless implementation reveals a current contract
|
|
mismatch; CLI docs remain authoritative.
|
|
- Exit commands: focused CLI parser/action tests and help commands, then the
|
|
standard repository commands.
|
|
|
|
### Stage 48: Retire Dormant Prompt And Generated-Text Surfaces
|
|
|
|
- Findings: `AUD-072`.
|
|
- Affected areas: unused prompt YAML loading/saving, normalized generated JSON
|
|
returns, and their sole-purpose tests and documentation.
|
|
- Work: verify these prompt/generated-text compatibility surfaces still have no
|
|
production owner, then remove them. If a production consumer appears, stop
|
|
and replace this retirement sequence with a separately approved contract.
|
|
- Locked behavior: normal Build/Validate/MarshalYAML, report publication,
|
|
comparison data packages, prompt debugging, typed normalization, and all
|
|
workflows remain unchanged.
|
|
- Documentation owners: prompt-input and generated-text internal documents;
|
|
remove stale descriptions rather than documenting retired APIs.
|
|
- Exit commands: graph/text caller checks, focused promptinput/generatedtext
|
|
tests, then the standard repository commands.
|
|
|
|
### Stage 49: Retire Dormant Weather Persistence Helpers
|
|
|
|
- Findings: none; this continues the dormant-surface remediation begun in
|
|
Stage 48.
|
|
- Affected areas: Weather API bundle saving, the JSON atomic helper if it
|
|
becomes orphaned, and sole-purpose tests and documentation.
|
|
- Work: verify these persistence helpers still have no workflow owner, then
|
|
remove them and any helper made unreachable by that removal. If a production
|
|
consumer appears, stop and seek a separately approved contract.
|
|
- Locked behavior: weather collection, normalized in-memory bundles, prompt
|
|
debugging, operator-owned publication, and all workflows remain unchanged.
|
|
- Documentation owners: weather-data and collection internals where stale
|
|
persistence claims exist.
|
|
- Exit commands: graph/text caller checks, focused weatherapi/weatherdata/
|
|
fileutil tests, then the standard repository commands.
|
|
|
|
### Stage 50: Retire Dormant Module And Forecast Compatibility Exports
|
|
|
|
- Findings: none; this continues the dormant-surface remediation begun in
|
|
Stage 48.
|
|
- Affected areas: module snapshot compatibility implications, unused forecast
|
|
threshold exports, and sole-purpose tests and documentation.
|
|
- Work: verify the identified exports still have no production owner, then
|
|
remove them without broadening the supported compatibility contract. If a
|
|
production consumer appears, stop and seek a separately approved contract.
|
|
- Locked behavior: current module snapshots, real forecast decisions, prompt
|
|
exports, report rendering, and all workflows remain unchanged.
|
|
- Documentation owners: module, briefing, and forecast internals where stale
|
|
compatibility claims exist.
|
|
- Exit commands: graph/text caller checks, focused module/briefing/forecast
|
|
tests, then the standard repository commands.
|
|
|
|
### Stage 51: Narrow Dormant Alert Envelope Copies
|
|
|
|
- Findings: none; this completes the dormant-surface remediation begun in
|
|
Stage 48.
|
|
- Affected areas: unused full alert-envelope copies, retained alert item
|
|
provenance, and sole-purpose tests and documentation.
|
|
- Work: remove unconsumed alert-envelope data while retaining exactly the item
|
|
and provenance values required by current facts, briefing, and report paths.
|
|
If a production consumer appears, stop and seek a separately approved
|
|
contract.
|
|
- Locked behavior: alert selection, alert item provenance, briefing digests,
|
|
report rendering, and all workflows remain unchanged.
|
|
- Documentation owners: weather-data, facts, and briefing internals where the
|
|
narrowed value is described.
|
|
- Exit commands: graph/data-flow checks plus focused weatherdata/facts/
|
|
briefing tests, then the standard repository commands.
|
|
|
|
### Stage 52: Consolidate Generated-Text Test Ownership
|
|
|
|
- Findings: `AUD-039`.
|
|
- Affected areas: generated-text day-style and render-context tests,
|
|
promptassets schema tests, and reporttemplate tests.
|
|
- Work: keep one shared semantic suite plus thin report-identity cases; put
|
|
schema ownership in promptassets and Markdown ownership in reporttemplate;
|
|
retain one real typed-context render integration.
|
|
- Locked behavior: every public validator identity, distinct Hourly behavior,
|
|
schema/type agreement, typed projection, template semantics, and composition
|
|
remain protected.
|
|
- Documentation owners: none.
|
|
- Exit commands: focused promptassets/generatedtext/reporttemplate tests, then
|
|
the standard repository commands.
|
|
|
|
### Stage 53: Reconcile Stale Internal Implementation Guides
|
|
|
|
- Findings: `AUD-075`.
|
|
- Affected areas: forecast derivation, collection, report registry, and prompt-
|
|
input internal guides plus incoming links.
|
|
- Work: replace nonexistent API/flow/test claims with concise descriptions of
|
|
the implemented owners and link to canonical contracts instead of duplicating
|
|
volatile details.
|
|
- Locked behavior: documentation-only; no executable contract changes.
|
|
- Documentation owners: the four affected `docs/internal/` files and
|
|
`docs/development.md` only if task routing changes.
|
|
- Exit commands: repository link/fence checks, focused test inventories used to
|
|
verify claims, `GOWORK=off go test -count=1 ./...`, and `git diff --check`.
|
|
|
|
### Stage 54: Retire Completed Comparison Roadmaps
|
|
|
|
- Findings: `AUD-076`.
|
|
- Affected areas: `docs/roadmap/profile-comparison.md`,
|
|
`docs/roadmap/implementation.md`, and all incoming links.
|
|
- Work: verify useful implemented contracts have one durable canonical owner,
|
|
repair incoming navigation, then remove the completed roadmaps so they no
|
|
longer duplicate current behavior.
|
|
- Locked behavior: documentation lifecycle only; no code, tests, dependencies,
|
|
schemas, or current contracts change.
|
|
- Documentation owners: CLI, operations, comparison integration/publication,
|
|
comparison execution, Promptkit integration, architecture, and development
|
|
docs only where an incoming link or missing durable fact requires correction.
|
|
- Exit commands: repository link/fence checks, both CLI help commands,
|
|
`GOWORK=off go test -count=1 ./...`, and `git diff --check`.
|
|
|
|
### Stage 55: Verify Remediation Completion And Durable Ownership
|
|
|
|
- Findings: none; this is the roadmap lifecycle gate.
|
|
- Prerequisite: Stages 1-54 are complete and every referenced finding's tests
|
|
and canonical documentation have landed.
|
|
- Affected areas: every remediation completion note, canonical documentation
|
|
owner, audit finding, retained decision, and incoming audit-document link.
|
|
- Work: verify every finding is resolved, superseded, or explicitly moved to a
|
|
newly approved roadmap; verify durable rationale lives with its canonical
|
|
owner; and produce a concise removal checklist for the temporary audit plan,
|
|
ledger, and remediation roadmap. Do not remove those records in this stage.
|
|
- Locked behavior: documentation lifecycle only; do not rewrite historical
|
|
ADRs or release notes and do not create a second current-state reference.
|
|
- Documentation owners: all durable owners touched by earlier stages, solely
|
|
to fill a demonstrated ownership gap.
|
|
- Exit commands: verify every stage/finding mapping and completion note;
|
|
repository link/fence and secret-pattern checks; all focused stage exits;
|
|
`GOWORK=off go test -count=1 ./...`,
|
|
`GOWORK=off go test -race -count=1 ./...`, both CLI help commands,
|
|
`GOWORK=off go vet ./...`, and `git diff --check`.
|
|
|
|
### Stage 56: Retire The Completed Audit Records
|
|
|
|
- Findings: none; this is the final documentation lifecycle change.
|
|
- Prerequisite: Stage 55 has verified completion and supplied the exact removal
|
|
and link-repair checklist.
|
|
- Affected areas: `docs/roadmap/audit.md`, `audit-plan.md`, this roadmap, and
|
|
their incoming links.
|
|
- Work: apply Stage 55's checklist, repair incoming navigation, and remove the
|
|
temporary audit plan, ledger, and remediation roadmap without changing
|
|
executable behavior or historical records.
|
|
- Locked behavior: documentation lifecycle only; durable current contracts and
|
|
rationale remain with their canonical owners, and ADRs and release notes are
|
|
unchanged.
|
|
- Documentation owners: only the navigation or durable owner files identified
|
|
by Stage 55.
|
|
- Exit commands: repository link/fence and secret-pattern checks;
|
|
`GOWORK=off go test -count=1 ./...`,
|
|
`GOWORK=off go test -race -count=1 ./...`, both CLI help commands,
|
|
`GOWORK=off go vet ./...`, and `git diff --check`.
|
|
|
|
## Completion Tracking
|
|
|
|
Update a stage heading or add a concise completion note only after its code,
|
|
tests, canonical documentation, and exit commands pass together. A stage that
|
|
begins a multi-stage remediation sequence must not mark its finding resolved
|
|
until the final continuation stage succeeds. Do not copy implemented contracts
|
|
into this roadmap. When all work is complete, follow Stages 55 and 56 rather
|
|
than retaining this file as a parallel reference.
|