Files
weatherreporter/docs/roadmap/ephemeral-state.md

383 lines
18 KiB
Markdown

# Ephemeral Operational State Roadmap
Status: Accepted feature direction; implementation has not started.
## Purpose
Weatherreporter should treat generated weather reports and their intermediate
artifacts as short-lived operational material rather than a durable audit
history. Forecasts and current conditions change continuously, and the normal
response to an old or failed report is to generate a new report, not to
reconstruct the provenance of the old one.
The application should retain only the bounded state needed to publish the
current report, calculate Recent Changes against the last successfully
published report for the same valid period, and complete the current
invocation safely. Detailed LLM diagnostics should remain an explicit,
operator-controlled exception outside ordinary workspace state.
This roadmap defines the intended state lifecycle, compatibility policy, and
architectural boundaries. A separate implementation plan will define the
ordered work after the roadmap is complete.
## User Intent
The state model should reflect these product expectations:
- weather reports are ephemeral products, not business records;
- old report provenance has no continuing operational value once conditions
and forecasts have changed;
- regenerating is preferable to recovering, replaying, or inspecting an old
generation;
- routine operation should not accumulate unbounded run-addressed artifacts;
- Recent Changes remains useful, but needs only one prior successful snapshot
for the same report and valid period; and
- sensitive prompt and response capture remains opt-in and explicitly managed
by the operator.
## Current State
Each generation currently writes a run-addressed collection containing a
module snapshot, data package, prompt preparation receipt, prompt execution
receipt, raw generated text, validated generated text, render context, managed
report, metadata, and optional notification receipt. Successful and failed
runs accumulate beneath the workspace.
Metadata links the collection and supports lookup by RunID. The CLI can list
historical runs and inspect their metadata, modules, data packages, prior
snapshots, and source provenance. New metadata uses the V2 format while the
reader retains V1 compatibility. Prompt artifacts are validated against
current report and prompt definitions when saved and loaded.
Most of this persistence exists for retrospective inspection and failure
recovery. Dedicated prompt preparation and execution load operations have no
ordinary production consumer. The important exception is module snapshot
state: generation actively loads the most recent compatible snapshot to build
the deterministic Recent Changes input for Daily, Today, and Tomorrow.
## Desired End State
Weatherreporter has three distinct state classes:
| State class | Lifecycle | Purpose |
| --- | --- | --- |
| Invocation workspace | Temporary and unpublished | Hold intermediate values while one report or batch is running. |
| Current published state | Bounded and replaceable | Hold the current managed report and the minimal deterministic snapshot or manifest needed for normal operation. |
| Secure LLM debug capture | Explicitly enabled and operator-managed | Diagnose prompt rendering or provider output when the operator deliberately requests sensitive capture. |
Ordinary generation uses an invocation-scoped temporary directory on the same
filesystem as the managed workspace when atomic publication requires it.
Prompt preparation, prompt execution, raw generated text, validated generated
text, render contexts, data packages, and notification receipts may exist
there while needed, but they are not published as durable historical
artifacts.
A successful report atomically replaces the current published state for its
logical report key and valid period. A failed attempt leaves the last
successfully published report and comparison snapshot unchanged. Ordinary
temporary artifacts are removed after both success and handled failure;
cleanup failure is reported safely but must not replace the primary generation
error.
RunIDs remain useful as in-process correlation identifiers in action results,
logs, provider provenance, and optional debug paths. They no longer identify a
durable collection that Weatherreporter promises to locate or decode later.
## Published Report Policy
The managed Markdown report remains the authoritative upload source during an
invocation. The intended default is to retain only the current managed report
for each logical report key and valid period, replacing it atomically after a
new report has been fully rendered and validated.
An explicit `--out` or `--out-dir` copy remains operator-owned output outside
the managed-state lifecycle. Weatherreporter does not delete, rotate, or
rewrite those copies except when the same explicit destination is selected by
a later invocation.
Distributor continues to receive only a completed managed Markdown report.
Notification success or failure does not create a durable notification
history. A notification failure leaves the newly published report available
and returns a safe error through the current action result.
## Recent Changes State
Recent Changes must be preserved without preserving general report history.
For Daily, Today, and Tomorrow, Weatherreporter retains at most one compatible
module snapshot for each logical report key and valid period.
The retained snapshot represents the last successfully published report. A
new invocation reads it before constructing Recent Changes and replaces it
only when the new managed report has been successfully validated, rendered,
and published. A failed generation therefore does not become the baseline for
the next report and cannot hide changes that the user has not yet seen.
Hourly does not currently use the comparison strategy and should not retain a
comparison snapshot solely for symmetry. State whose valid period has ended
and can no longer participate in a supported comparison is eligible for safe
cleanup.
## Temporary Workspace And Failure Semantics
Temporary state must remain beneath a narrowly owned application directory and
use safe path construction, restrictive permissions where content is
sensitive, and atomic writes where practical. Publication must not expose a
partially rendered report or a snapshot that does not correspond to the
published report.
Normal results retain bounded error information and paths only for artifacts
that remain meaningful after the command: a previously or newly published
report, an explicit operator output, or an enabled secure debug capture.
Temporary intermediate paths are not emitted as if they were durable recovery
locations. A failed command is retried by starting a new generation.
Process interruption may leave an uncommitted temporary directory. Such a
directory is never considered published state, is never selected for Recent
Changes, and may be removed by a documented safe cleanup mechanism. Cleanup
must distinguish inactive temporary directories from concurrent active
invocations and must never recursively target the workspace root or an
unresolved configuration path.
## Inspection And Metadata Policy
Run-history discovery and inspection are not part of the desired product
contract. The historical `inspect reports`, `inspect metadata`, `inspect
modules`, `inspect data-package`, `inspect prior`, and `inspect sources`
surfaces are candidates for removal together rather than preservation through
a new storage representation.
Any manifest retained for atomic publication or Recent Changes is current
operational state, not an archival metadata record. It should contain only the
identity, valid period, safe paths, and deterministic snapshot information
needed to validate and use that current state. It does not need to preserve
prompt messages, generated prose intermediates, source provenance, provider
provenance, notification history, or a catalog of prior runs.
The application does not promise cross-version decoding of ordinary workspace
state. A new release may replace or ignore incompatible current-state files,
provided it fails safely, never mistakes stale state for a compatible Recent
Changes baseline, and documents any operator action required during upgrade.
## Prompt Execution And Debugging
Prompt inspection before weather collection and prepared execution remain
runtime safety requirements. They do not require durable preparation or
execution receipts.
The selected logical profile, effective backend and model, validation outcome,
and safe classified error remain available to the active workflow and its CLI
summary where useful. Weatherreporter does not retain them as long-term report
provenance after the invocation completes.
The existing explicit secure debug root remains outside ordinary state and may
retain rendered prompts, schemas, input bodies, generated bodies, and effective
parameters according to its documented contract. Weatherreporter does not
automatically clean that operator-selected location. Credentials must remain
excluded from debug capture.
## Compatibility And Upgrade Policy
This is an intentional breaking change to the workspace and inspection
contracts. Weatherreporter does not need to migrate historical V1 or V2
metadata, prompt receipts, intermediate generated-text artifacts, or managed
reports into the new representation.
Legacy workspace trees must not be silently interpreted as current published
state. They also must not be deleted automatically merely because a new
version starts: an operator may have placed or referenced files there despite
the absence of a continuing application compatibility promise. Release notes
and operations documentation must explain whether legacy data can be removed
manually and identify the exact safe target.
The change should land in a release whose notes clearly identify removed CLI
commands, obsolete paths and schemas, the new bounded state behavior, and any
upgrade action. Because Weatherreporter remains pre-1.0, the ordinary semantic
version policy may carry this breaking change without inventing a migration
framework.
## Required Architecture Decision Record
The implemented feature must include an Accepted ADR recording the durable
architectural decision to use ephemeral operational state. The ADR is not part
of this roadmap-writing pass and should not be created until implementation is
being prepared.
The ADR should record:
- the mismatch between run-addressed provenance storage and the ephemeral
weather-report lifecycle;
- the decision to retain bounded current report and comparison state rather
than historical runs;
- the distinction between temporary invocation state, published operational
state, explicit output copies, and secure debug capture;
- the removal of historical inspection and backward-compatibility guarantees;
- atomic publication and failed-run behavior;
- the alternatives considered, including retaining the current archive,
adding time-based retention, or keeping a bounded run history; and
- consequences for CLI compatibility, workspace layout, testing, operations,
and future schema changes.
Once accepted, the ADR owns the decision rationale. The architecture policy
owns the resulting current invariant, while focused state, CLI, operations,
and integration documents own the implemented contracts.
## Scope
The completed feature includes:
- an invocation-scoped temporary workspace for intermediate generation state;
- atomic publication of the current managed report and its minimal operational
state;
- a bounded comparison snapshot representing the last successfully published
report for each supported report key and valid period;
- safe cleanup behavior for normal completion, handled failure, and abandoned
temporary workspaces;
- removal of durable prompt preparation, prompt execution, generated-text,
render-context, data-package, notification, and run-metadata history;
- removal of run-history inspection commands and their application/state
contracts;
- removal of V1 metadata compatibility and current-version coupling for
historical prompt artifacts by removing the historical artifact contract;
- preservation of active-command partial status, safe errors, and paths to
genuinely retained published, operator-owned, or debug outputs;
- preservation of explicit output copies, Distributor upload behavior, and
opt-in secure LLM debug capture;
- risk-appropriate offline tests for atomic publication, comparison baselines,
failure isolation, cleanup safety, concurrent invocation safety, and absence
of unbounded state growth;
- an Accepted ADR documenting the architectural decision; and
- updates to canonical architecture, CLI, operations, configuration,
troubleshooting, integration, internal, testing, and release documentation
where their contracts change.
## Non-Goals
This feature does not include:
- a general-purpose cache, database, archival service, or retention engine;
- replaying or resuming interrupted generation;
- migrating legacy artifacts into the new representation;
- retaining a bounded number of historical runs for convenience;
- automatic upload or archival of state to remote storage;
- collecting additional provider telemetry or weather-source provenance;
- changing report content, prompt text, schemas, profile selection, weather
derivation, or batch membership;
- deleting operator-owned `--out`, `--out-dir`, or secure debug files;
- changing Distributor's report-content contract; or
- making live external services part of the default test suite.
## Safety And Testing Policy
The state refactoring must preserve Weatherreporter's existing path-safety and
atomicity expectations while reducing the amount of durable state. Tests
should emphasize observable lifecycle guarantees rather than private file
choreography.
Important risks requiring durable offline coverage include:
- a failed or canceled generation replacing a previously published report or
comparison baseline;
- a partially written report becoming visible as current;
- Recent Changes selecting an incompatible report, valid period, or failed
attempt;
- cleanup deleting published, operator-owned, debug, or concurrently active
files;
- batch partial success corrupting the state of another report;
- notification failure rolling back or obscuring a successfully published
report;
- stale or incompatible current state being treated as valid; and
- repeated successful and failed runs causing unbounded ordinary workspace
growth.
Tests remain deterministic, offline, credential-free, and based on real
temporary filesystems plus narrow external-boundary fakes. Race-enabled tests
are required where publication, cleanup, or concurrent invocation behavior
shares mutable filesystem state.
## Relationship To Domain-Specific Profiles
The domain-specific profile feature can be implemented before this refactor,
but it should not add new historical compatibility or durable-provenance
commitments. Profile inspection, selection, override precedence, and effective
model resolution remain active-workflow behavior and survive the state change.
The domain-profile roadmap and implementation plan should acknowledge that
prompt artifacts from version `1.0.1` need not remain readable after prompts
advance to `1.1.0`. Existing state persistence may remain temporarily while
the profile feature lands, but it should not be expanded or treated as the
target architecture.
## Completion Criteria
The roadmap's target state is achieved when:
- ordinary runs no longer create durable run-addressed artifact collections;
- a successful report atomically replaces only the corresponding current
published state;
- failed and canceled attempts leave the prior published report and Recent
Changes baseline unchanged;
- Daily, Today, and Tomorrow compare against at most one compatible snapshot
from the last successfully published report;
- expired comparison and published state can be removed safely without
touching operator-owned or active files;
- Hourly does not retain an unused comparison snapshot;
- historical inspection commands and V1/V2 archival compatibility code are
removed;
- temporary, published, explicit-output, and debug paths have distinct and
documented ownership and cleanup rules;
- Distributor and active-command summaries continue to receive the completed
report and safe status information they require;
- the default suite proves atomicity, bounded growth, cleanup safety, batch
isolation, and comparison correctness offline;
- an Accepted ADR records the architectural decision and alternatives; and
- canonical current-state documentation describes only the implemented
lifecycle.
## Open Questions
### Lifetime of the current managed report
Recommendation: retain one current managed report per logical report key and
valid period until it is replaced or its valid period expires. This preserves
the current default behavior for invocations without `--out` while bounding
growth.
Alternative: treat the managed report as temporary and retain output only when
the operator supplies `--out` or `--out-dir`. This minimizes state further but
makes a successful default invocation produce no durable report for the user
and complicates Distributor sequencing.
### Historical inspection replacement
Recommendation: remove the run-history inspection commands without adding a
replacement initially. Current command summaries, current managed files, and
opt-in debug capture cover the remaining supported workflows.
Alternative: add a narrow `inspect current REPORT` command backed only by the
current operational manifest. This provides discoverability without history,
but it creates a new public surface and may preserve metadata complexity that
the refactor is intended to remove.
### Abandoned temporary workspace cleanup
Recommendation: use an explicitly owned temporary subtree with per-invocation
ownership markers and a conservative age threshold. Normal cleanup removes the
current invocation synchronously; opportunistic cleanup removes only marked,
inactive directories old enough that they cannot reasonably belong to a live
invocation.
Alternative: perform only synchronous cleanup and document manual removal of
directories left by process termination. This minimizes destructive code and
concurrency risk, but crashed processes can still accumulate unbounded files.
### Legacy workspace cleanup
Recommendation: ignore legacy run-addressed trees and document a precise,
manual one-time cleanup procedure. Do not automatically delete them during
startup or upgrade.
Alternative: add an explicit cleanup command that previews and then removes
recognized legacy artifacts. This is more convenient for large installations
but introduces a destructive command and a legacy-format classifier that must
be maintained and tested.