Rename rolling report to hourly

This commit is contained in:
2026-06-14 04:26:05 +00:00
parent b3f7c9c1f2
commit 8d737395dc
28 changed files with 220 additions and 600 deletions

View File

@@ -4,8 +4,8 @@
This roadmap defines planned work to move selected reports from full Markdown
LLM generation to deterministic Markdown rendering with structured LLM-filled
text slots. The first target report is the rolling next-hours report, now named
`hourly` rather than `near_term`.
text slots. The first target report is the rolling next-hours report, named
`hourly`.
This feature is not implemented yet, so this document lives under
`docs/roadmap/`.
@@ -67,15 +67,14 @@ not become a second application logic layer.
Schema dependency in the first implementation.
- Do not generate schemas or templates from inline Go.
- Start with the rolling next-hours report only.
- Rename the planned `near_term` report to `hourly`.
- Do not keep both `near_term` and `hourly` public report IDs.
- Use `hourly` as the only public report ID for the rolling next-hours
report.
- Do not keep compatibility aliases from retired roadmap terminology.
- Do not add a generic workflow engine or plugin system.
## Hourly Report Target
The planned `near_term` report should become the `hourly` report.
Target report identity:
The rolling next-hours report target identity is:
- report ID: `hourly`
- CLI command: `weatherreporter generate hourly`
@@ -143,7 +142,7 @@ Keep the first schema small. Example shape:
```json
{
"summary": "Brief near-term overview.",
"summary": "Brief hourly overview.",
"timing": "Plain-language timing of notable changes.",
"impacts": "Practical impacts for the next few hours.",
"confidence": "Optional confidence or uncertainty note."

View File

@@ -7,8 +7,8 @@ This roadmap defines the concrete implementation sequence for
will implement each stage in order.
This is a future-work roadmap. Until a stage is implemented, non-roadmap docs
must not describe `GeneratedText`, embedded report templates, or
`weatherreporter generate hourly` as available behavior.
must not describe `GeneratedText`, embedded report templates, or other
unimplemented GeneratedText behavior as available.
## Source Feature Roadmap
@@ -26,8 +26,8 @@ for reaching that shape.
- Implement the first GeneratedText path for the rolling next-hours report,
named `hourly`.
- Replace planned/public `near_term` naming with `hourly`; do not keep a
public `near-term` alias.
- Use `hourly` as the only planned public name for the rolling next-hours
report; do not keep compatibility aliases from retired roadmap terminology.
- Use report ID `hourly`, artifact group `hourly`, batch output name
`hourly.md`, and CLI command `weatherreporter generate hourly`.
- Keep the rolling report explicit-generation only; do not add scheduled batch
@@ -61,7 +61,7 @@ planned public name for the rolling next-hours report.
Files to inspect:
- `docs/roadmap/generated-text.md`
- `docs/roadmap/near-term.md`
- the superseded roadmap file for the retired rolling-report name
- `docs/roadmap/future.md`
- `docs/roadmap/implementation.md`
- `internal/app/app.go`
@@ -70,30 +70,32 @@ Files to inspect:
Implementation:
- Replace `docs/roadmap/near-term.md` with a short superseded note pointing to
`docs/roadmap/generated-text.md`, or delete it if the repository policy at
implementation time prefers removing obsolete roadmap files.
- Ensure no roadmap instructs a future agent to implement public
`near_term` / `near-term` behavior.
- If partial `near_term` code already exists, rename it to `hourly` rather
than adding aliases:
- `ReportNearTerm` -> `ReportHourly`;
- `report.NearTerm` -> `report.Hourly`;
- CLI command `near-term` -> `hourly`;
- artifact group `near-term` -> `hourly`;
- Replace the superseded roadmap file for the retired rolling-report name with
a short note pointing to `docs/roadmap/generated-text.md`, or delete it if
the repository policy at implementation time prefers removing obsolete
roadmap files.
- Ensure no roadmap instructs a future agent to implement retired public
identifiers for the rolling report.
- If partial code using retired identifiers already exists, rename it to
`hourly` rather than adding aliases:
- app report kind -> `ReportHourly`;
- report ID constant -> `report.Hourly`;
- CLI command -> `hourly`;
- artifact group -> `hourly`;
- prompt IDs and tests updated to hourly names.
- Do not add compatibility aliases for `near-term`.
- Do not add compatibility aliases for retired command or config names.
Acceptance criteria:
- Active roadmap docs use `hourly` for the rolling report.
- No active roadmap describes `near_term` as the target public report ID.
- No active roadmap describes a retired identifier as the target public report
ID.
- Existing code compiles after any rename work.
Suggested validation:
```bash
rg -n "near_term|near-term|NearTerm" docs internal
rg -n 'near[_-]term|Near''Term' docs internal
go test ./internal/app ./internal/report ./internal/cli
```
@@ -208,7 +210,7 @@ Implementation:
- no daily summaries, daypart summaries, or storm summary.
- Add config report aliases:
- `hourly`
- reject or do not recognize `near_term` / `near-term`.
- reject or do not recognize retired rolling-report config keys.
- Add app report kind `ReportHourly = "hourly"` and map it to
`report.Hourly`.
- Add CLI parsing and help for:
@@ -651,17 +653,17 @@ Files to inspect:
Implementation:
- Add CLI command tests for `generate hourly`.
- Reject `generate near-term`.
- Reject the retired rolling-report command name.
- Reject hourly `--date`, `--start`, `--end`, and duration-like flags.
- Add config override tests for `reports.hourly.deterministic_modules`.
- Ensure `near_term` and `near-term` report config keys are rejected.
- Ensure retired rolling-report config keys are rejected.
- Add app/CLI workflow tests using fake Scriptorium structured output.
- Update examples only if they enumerate report module overrides.
Acceptance criteria:
- `weatherreporter --help` lists `generate hourly`;
- `generate near-term` is not accepted;
- the retired rolling-report command name is not accepted;
- hourly config overrides validate compatible modules;
- incompatible daily/daypart modules fail clearly for hourly;
- examples load successfully.
@@ -693,13 +695,13 @@ Files to inspect and update:
- new `docs/internal/reporttemplate.md`
- `docs/integrations/scriptorium.md`
- `docs/roadmap/future.md`
- `docs/roadmap/near-term.md`
- the superseded roadmap file for the retired rolling-report name
- `examples/config.yml`, only if examples changed
Documentation requirements:
- Non-roadmap docs describe only implemented hourly and GeneratedText behavior.
- `docs/cli.md` documents `generate hourly`, not `generate near-term`.
- `docs/cli.md` documents `generate hourly`, not the retired command name.
- `docs/config.md` documents `reports.hourly` only if override support is
implemented.
- Internal docs distinguish:
@@ -711,20 +713,22 @@ Documentation requirements:
- Scriptorium integration docs include the structured-output command actually
used by the adapter.
- State docs list generated-text artifacts and metadata links.
- `docs/roadmap/near-term.md` is deleted or marked superseded.
- the superseded roadmap file for the retired rolling-report name is deleted
or marked superseded.
- Deferred migrations for other report types stay under roadmap docs only.
Acceptance criteria:
- No non-roadmap docs describe unimplemented generated-text migrations.
- No active docs describe `near_term` as the target public report.
- No active docs describe retired rolling-report identifiers as the target
public report.
- Maintained examples remain valid.
Suggested validation:
```bash
go test ./internal/config
rg -n "near_term|near-term|NearTerm" docs internal examples
rg -n 'near[_-]term|Near''Term' docs internal examples
git diff --check
```
@@ -745,7 +749,7 @@ git diff --check
Manual checks:
- `weatherreporter --help` lists `generate hourly`.
- `weatherreporter --help` does not list `generate near-term`.
- `weatherreporter --help` does not list the retired rolling-report command.
- generated hourly Markdown has deterministic headings and section order.
- GeneratedText JSON is persisted separately from deterministic facts.
- render context JSON is persisted and readable.

View File

@@ -1,363 +1,6 @@
# Near-Term Report Roadmap
# Superseded Roadmap
## Purpose
This roadmap has been superseded by `docs/roadmap/generated-text.md`.
This roadmap defines planned work to add a rolling `near_term` report focused
on the next several hours. The feature is not implemented yet, so this document
lives under `docs/roadmap/`.
The goal is a frequently generated report that helps readers understand what
matters in the immediate future: current conditions, hourly evolution,
precipitation timing, applicable hazards, applicable SPC risk products, and the
most relevant short-term narrative context.
## Target Behavior
Add a generated report with:
- report ID: `near_term`
- display name: `Near-Term Report`
- prompt ID: `weather.near_term_report`
- artifact group: `near-term`
- batch output name: `near-term.md`
- default valid-period length: 6 hours
- valid period: `[generation_time, generation_time + nearTermHours)`
The report should use a package-owned constant for the valid-period length, for
example:
```go
const nearTermHours = 6
```
Do not make the duration configurable in the first implementation. The constant
exists so the value can be changed later to 4 or 8 hours without changing
valid-period logic in multiple places.
## Locked Decisions
- The report ID is `near_term`.
- The report is rolling and generation-time anchored, not civil-day anchored.
- The first implementation covers the next 6 hours through a constant.
- The report should be generated explicitly by CLI command before deciding
whether it belongs in scheduled batches.
- The first implementation should declare `rolling_window` comparison policy
but should not emit Recent Changes output for `near_term`.
- Alert and SPC products should be included only when their valid periods
overlap the resolved near-term report period.
- SPC discussion text should keep the existing categorical-risk threshold rule
and should still require overlap with the near-term report period.
- The AFD stanza should include key messages and short term text by default.
- Daily-only modules should not be forced into this report.
## Report Definition
Add a report definition under `internal/report`, preferably in a focused
`near_term_report.go` file.
Definition fields:
- `ID`: `NearTerm`
- `Name`: `Near-Term Report`
- `PromptID`: `weather.near_term_report`
- `ComparisonStrategy`: `rolling_window`
- `ArtifactGroup`: `near-term`
- `BatchOutputName`: `near-term.md`
- `Generated`: `true`
- `CompatiblePriorIDs`: `[]ID{NearTerm}`
- `Modules`: near-term module list below
- `resolve`: rolling near-term resolver
Valid-period resolver:
```go
func resolveNearTerm(req ResolveRequest) (timeutil.Period, error) {
localNow := req.Now.In(req.Location)
return timeutil.Period{
Start: localNow,
End: localNow.Add(nearTermHours * time.Hour),
}, nil
}
```
The implementation should use idiomatic package-local constants and avoid
duplicating duration literals in tests or app code.
## Default Module Composition
Default module order should be:
1. `metadata`
2. `current_conditions`
3. `hourly_forecast`
4. `precip_timing`
5. `alert_digest`
6. `spc_convective_outlooks`
7. `area_forecast_discussion`
8. `spc_convective_discussion`
9. `weather_story`
`area_forecast_discussion` should use options equivalent to:
```yaml
sections:
- key_messages
- short_term
```
Do not include these daily/daypart-oriented modules initially:
- `derived_daily_summary`
- `derived_daypart_summaries`
- `outdoor_windows`
- `tomorrow_planning`
If the report needs deterministic summary facts later, add a purpose-built
module such as `derived_near_term_summary` rather than stretching daily modules
into a rolling sub-daily context.
## Prompt Package Shape
The existing prompt-input category layout should remain unchanged:
- `applicable_risk_products`
- `derived_summaries`
- `narrative_products`
- `raw_data`
Near-term output is expected to emphasize:
- `current_conditions` and `hourly_forecast` under `raw_data`
- `precip_timing` under `derived_summaries`
- `alert_digest` and `spc_convective_outlooks` under
`applicable_risk_products`
- `area_forecast_discussion`, `spc_convective_discussion`, and
`weather_story` under `narrative_products`
Module interval fields should use the existing prompt-facing
`period_begins` / `period_ends` convention.
## Overlap And Filtering Rules
Hourly forecast:
- use only hourly periods overlapping the near-term valid period;
- preserve hourly period order;
- do not include the full daily forecast.
Narrative products:
- AFD key messages and short term text may be included because the AFD is an
official short-term forecast discussion product;
- narrative forecast periods are not included by default unless a later prompt
test shows they improve near-term output.
Alerts:
- include active alert overlaps only when the alert overlaps the near-term
valid period;
- if alerts were checked successfully and no alerts overlap, emit checked empty
alert context through existing module behavior.
SPC outlooks:
- include only retained outlooks whose valid periods overlap the near-term
valid period;
- do not include non-overlapping outlooks even if they are severe;
- keep current prompt-facing field exclusions for geometry, severity rank,
expiration time, and source URL.
SPC discussion:
- include discussion only for SPC days where a retained overlapping categorical
outlook has severity rank at least `3`;
- do not include discussion for low-risk, non-categorical-only, or
non-overlapping outlooks.
Weather story:
- include when available under current optional-source behavior;
- do not require the story valid period to exactly match the near-term period
unless later testing shows stale stories are a problem.
## Implementation Stages
### Stage 1: Report Registry
Goal: add the `near_term` report definition and valid-period resolver.
Files to inspect or update:
- `internal/report/definition.go`
- `internal/report/registry.go`
- `internal/report/period.go`
- new `internal/report/near_term_report.go`
- `internal/report/period_test.go`
- `docs/internal/report-registry.md` after implementation
Acceptance criteria:
- `report.DefaultRegistry().Lookup(report.NearTerm)` succeeds.
- `report.Registry.All()` includes the report in a stable order.
- resolving the report at a fixed generation time produces a half-open
six-hour period.
- report metadata and RunID include `near_term`.
### Stage 2: Module Compatibility And Defaults
Goal: allow existing relevant modules to build for `near_term` and define the
default near-term composition.
Files to inspect or update:
- `internal/briefing/modules.go`
- `internal/report/near_term_report.go`
- `internal/briefing/*_module_test.go`
- `internal/module/module_test.go`
Acceptance criteria:
- all default near-term modules validate and build from appropriate test facts;
- daily-only modules remain incompatible unless intentionally expanded;
- `area_forecast_discussion` defaults to key messages and short term only for
this report.
### Stage 3: Derived Facts
Goal: make `internal/facts` derive report-period facts for `near_term`.
Files to inspect or update:
- `internal/facts/facts.go`
- `internal/facts/facts_test.go`
- `internal/forecast` selection helpers, if needed
Acceptance criteria:
- valid-period hourly periods are sliced to the six-hour window;
- precipitation timing is built from that six-hour hourly slice;
- alert overlaps use the near-term valid period;
- SPC outlook and discussion derivation use the near-term valid period;
- no daily summaries or daypart summaries are required for the default
near-term module set.
### Stage 4: CLI And App Wiring
Goal: add explicit generation support without changing existing commands.
Files to inspect or update:
- `internal/app`
- `internal/cli`
- `cmd/weatherreporter/main.go`
- `docs/cli.md` after implementation
Expected command:
```bash
weatherreporter generate near-term [--config PATH] [--units VALUE] [--tz NAME] [--out PATH]
```
Acceptance criteria:
- command maps to `report.NearTerm`;
- no `--date`, `--start`, or `--end` flags are added for this report;
- existing `generate daily`, `generate tomorrow`, `generate three-day`,
`generate weekend`, and `generate storm` behavior is unchanged;
- CLI help lists the new command.
### Stage 5: Prompt Input And State Coverage
Goal: prove the managed module snapshot and data package contain the intended
near-term stanzas.
Files to inspect or update:
- `internal/app/app_test.go`
- `internal/promptinput`
- `internal/state`
Acceptance criteria:
- generated module snapshot includes the near-term default module list in
order;
- data package uses existing categories;
- alert/SPC stanzas are omitted or checked-empty according to current module
behavior and valid-period overlap;
- report metadata preserves canonical `valid_period`;
- module interval labels use `period_begins` and `period_ends`.
### Stage 6: Documentation And Examples
Goal: document implemented behavior only after the code exists.
Files to inspect or update after implementation:
- `docs/cli.md`
- `docs/internal/report-registry.md`
- `docs/internal/module.md`
- `docs/internal/facts.md`
- `docs/internal/briefing.md`
- `docs/config.md` only if report module overrides need an example update
- `examples/config.yml` only if it lists report module overrides
Acceptance criteria:
- non-roadmap docs describe `near_term` only after implementation;
- future or deferred near-term summary modules remain under roadmap docs;
- examples, if updated, load through existing config tests.
## Test Plan
Focused tests:
```bash
go test ./internal/report ./internal/briefing ./internal/facts
go test ./internal/app ./internal/cli ./internal/promptinput
```
Full validation:
```bash
go test ./...
go run ./cmd/weatherreporter --help
git diff --check
```
Important coverage:
- six-hour valid-period resolution from a fixed generation time;
- timezone-aware period start and end;
- no civil-day truncation;
- hourly periods selected by overlap with the rolling window;
- alert overlap filtering;
- SPC outlook filtering by overlap;
- SPC discussion filtering by overlap plus categorical severity threshold;
- AFD key messages and short term included;
- daily-only modules rejected or absent from default near-term composition;
- distributor bundle path templates render sensibly for a sub-daily report,
especially valid start time variables.
## Deferred Work
Do not include these in the first implementation:
- user-configurable near-term duration;
- adding `near_term` to scheduled morning or evening batches;
- a dedicated `derived_near_term_summary` module;
- narrative forecast periods by default;
- separate AFD section modules;
- near-term-specific Recent Changes comparison output;
- CLI flags for custom near-term duration.
## Open Questions
None block the roadmap.
Recommendation: implement the first version as explicit `generate near-term`
only, with no scheduled batch membership. That keeps the user-visible behavior
small while the prompt and generated report are tested.
Viable alternative: add `near_term` to a frequent scheduled batch immediately.
That may be useful operationally, but it should wait until the report cadence
and downstream distributor behavior are clear.
The rolling next-hours report is named `hourly`. Use the GeneratedText roadmap
for current future-work guidance.