15 KiB
Stateless Execution Roadmap
Status: Accepted.
Purpose
Weatherreporter should be a stateless report transformation pipeline. Each invocation fetches current inputs from the Weather API, derives deterministic facts, executes Promptkit, renders Markdown, and writes or distributes the completed report. It does not retain application-owned history or operational state between invocations.
Weather reports are ephemeral products rather than business records. Forecasts and current conditions change continuously, and the normal response to an old or failed report is to generate a new one rather than recover, replay, or inspect the prior generation.
This roadmap defines the desired lifecycle, output contract, compatibility policy, and architectural boundaries.
User Intent
The target design reflects these product expectations:
- each invocation is independent and requires no prior Weatherreporter state;
- routine operation creates only the requested report outputs;
- reports are written somewhere useful even when the operator omits an explicit output flag;
- Weatherreporter does not maintain forecast history merely to compare runs;
- regenerating replaces a same-named output atomically instead of creating an archive;
- Distributor receives the completed report produced by the current invocation; and
- sensitive diagnostics are retained only through an explicit, operator-controlled debug option.
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 configured workspace.
Metadata links these artifacts and supports lookup by RunID. The CLI can list historical runs and inspect their metadata, modules, data packages, prior snapshots, and source provenance. The reader retains V1 compatibility while new runs write V2 metadata.
Weatherreporter also loads a compatible prior module snapshot for Daily, Today, and Tomorrow and compares it with the current snapshot. Configurable thresholds determine whether structured Recent Changes are included in the Promptkit data package. This is the only current product behavior that depends on state from an earlier invocation.
Desired End State
Weatherreporter has no durable application-managed workspace. Its dataflow is:
Weather API input
-> deterministic facts and modules
-> Promptkit data package and generated text
-> repository-owned Markdown rendering
-> operator-owned report output
-> optional Distributor upload
Intermediate values remain in memory wherever practical. A narrowly scoped temporary file may be used when an external interface requires a file path, but it exists only for the active invocation and is removed on return. Temporary material is not a supported recovery or inspection surface.
RunIDs may remain as in-process correlation identifiers in action summaries, errors, Distributor idempotency values, and explicit debug paths. They do not identify a collection that Weatherreporter can locate or decode later.
Configuration files, operator-owned report outputs, and explicitly requested debug captures are inputs or outputs, not Weatherreporter state.
Report Output Contract
Every successful report generation writes one operator-owned Markdown output. An explicit output option selects its destination. When no explicit destination is supplied, Weatherreporter uses the process working directory captured at invocation start.
Default single-report filenames are:
| Report | Default output |
|---|---|
| Daily | daily-YYYY-MM-DD.md, using the report's valid local date |
| Today | today.md |
| Tomorrow | tomorrow.md |
| Hourly | hourly.md |
--out PATH replaces the default destination for generate; it no longer
means an extra copy of a separately managed report. Relative paths are resolved
from the invocation's working directory.
For run, --out-dir PATH selects the report-output directory and the current
working directory is the default when it is omitted. Existing batch filenames
remain: today.md, tomorrow.md, and daily-YYYY-MM-DD.md. Successful items
in a partially failed batch retain their outputs.
Output publication is atomic. A completed generation may atomically replace an existing file at the selected path, but a failed or canceled generation must not truncate or partially replace it. Weatherreporter does not rotate, archive, expire, or otherwise manage an output after publication.
The JSON action summary reports the final output path. It does not expose paths
to transient intermediates. --quiet continues to suppress the action summary,
not report creation.
Distributor Contract
Distributor uploads use the completed Markdown output from the active invocation. There is no separate durable managed-report copy and no workspace scan.
For a single report, local output publication completes before notification. A notification failure leaves the report output intact and returns a safe error through the active result. It does not create a notification receipt.
Batches continue to suppress per-report notification and attempt their batch-level upload only after every planned report succeeds. A report failure leaves other successful output files intact, skips the batch upload, and returns an aggregate failure. Distributor status remains active-workflow information rather than retained Weatherreporter history.
Recent Changes Deprecation And Removal
The local Recent Changes feature is deprecated by this accepted direction and is removed when the stateless execution change lands. Its low practical value does not justify retaining a historical state subsystem.
Removal includes:
- prior-snapshot discovery and compatibility rules;
- the
internal/changescomparison implementation; - report-registry comparison strategies and compatible-prior declarations;
recent_changeconfiguration and threshold validation;- Recent Changes values in application results, prompt inputs, fixtures, and tests;
- the
recent_changesPromptkit data-package stanza; and - prompt instructions that refer to supplied recent changes.
Removing the prompt-input field is a breaking prompt contract change. The data
package schema advances from weatherreporter.data_package.v3 to
weatherreporter.data_package.v4, and all four prompt definitions advance from
version 1.1.0 to 2.0.0 together.
Generated-text schemas and report templates do not change; neither has a
direct dependency on Recent Changes.
Weatherreporter does not retain an empty compatibility field and does not keep a local fallback comparator. Reports simply omit change commentary after this feature is removed.
A future upstream Weather API change product may allow Weatherreporter to reintroduce structured change commentary without local state. That work is recorded in Future Roadmap and is not a prerequisite for this refactor.
Debugging
Prompt inspection before weather collection and prepared execution remain runtime safety requirements. Preparation details, effective profile and model, validation outcomes, source warnings, and safe errors remain available to the active workflow and its action summary where useful.
The existing --llm-debug-dir PATH option remains the explicit exception to
stateless output. When supplied, it may retain rendered prompts, schemas, input
bodies, generated bodies, and effective parameters according to its secure
capture contract. The operator selects and manages that location;
Weatherreporter does not clean or archive it. Credentials remain excluded.
Adding a broader logging framework or an implicit persistent debug directory
is outside this feature. A future rename or generalization to --debug should
be considered separately so this state refactor does not expand the sensitive
capture contract incidentally.
Removed State And Inspection Contracts
The target removes:
- the
workspaceconfiguration section and its directory settings; - durable module snapshots, data packages, preparation and execution receipts, raw and validated generated text, render contexts, run metadata, managed reports, and notification receipts;
- historical artifact path fields from action results and summaries;
- V1 and V2 metadata models, readers, validators, and compatibility behavior;
- state lookup, prior selection, and run-history discovery; and
inspect reports,inspect metadata,inspect modules,inspect data-package,inspect prior, andinspect sources.
No replacement inspection command or current-state manifest is introduced. The active action summary, final output, command error, and opt-in debug capture are the supported diagnostic surfaces.
State-independent atomic file helpers may remain outside a state abstraction.
The target architecture should not preserve internal/state merely as a
compatibility wrapper after its state responsibilities disappear.
Compatibility And Upgrade Policy
This is an intentional breaking change to the CLI, configuration, prompt-input, workspace, and inspection contracts. Weatherreporter does not migrate old V1 or V2 metadata or other historical artifacts.
Legacy workspace trees are ignored. Weatherreporter must not discover, interpret, or automatically delete them. Release notes and operations documentation identify the obsolete configuration and commands and provide a precise manual cleanup procedure for operators who want to remove the legacy workspace.
Existing report files explicitly written through --out or --out-dir remain
operator-owned and are never treated as legacy workspace material.
The change should land in a release whose notes identify the removed Recent Changes behavior, configuration fields, inspection commands, artifact paths, and metadata compatibility; the new default output destinations; and any operator action required during upgrade.
Required Architecture Decision Record
The target state includes an Accepted ADR recording the durable decision to make Weatherreporter stateless.
The ADR should record:
- the mismatch between run-addressed provenance storage and ephemeral weather reports;
- the decision to remove local change detection rather than retain state for a rarely used report section;
- the transformation-pipeline model and operator-owned output boundary;
- the absence of historical inspection and backward-compatibility guarantees;
- atomic output and failure behavior;
- the separation of explicit debug capture from ordinary execution;
- the upstream-service path for any future forecast comparison; and
- alternatives considered, including the former bounded-current-state design, time-based retention, and a bounded run history.
Once accepted, the ADR owns the rationale. Architecture owns the resulting stateless invariant, while CLI, operations, configuration, integrations, and focused internal documents own implemented contracts.
Scope
The completed feature includes:
- removal of local Recent Changes and all prior-run dependencies;
- removal of the durable workspace, artifact persistence, metadata compatibility, and historical inspection surfaces;
- in-memory or invocation-temporary processing with safe cleanup;
- atomic operator-owned output for every successful report;
- current-working-directory defaults and explicit output overrides;
- preservation of report generation, batch membership, Promptkit execution, Distributor delivery, action summaries, and opt-in secure debug capture;
- removal or simplification of state-only packages, fields, configuration, fixtures, tests, and documentation;
- exact-version prompt updates for the breaking input-contract change;
- deterministic offline tests for output atomicity, failure isolation, default path selection, Distributor sequencing, and absence of durable state;
- an Accepted ADR documenting the decision; and
- canonical documentation describing the implemented contract and clear release-note requirements for the release that publishes it.
Non-Goals
This feature does not include:
- the future upstream forecast-change API or reintroduced change commentary;
- a cache, database, archive, retention engine, manifest, or resume mechanism;
- migration or automatic deletion of legacy workspace artifacts;
- retaining a bounded report or snapshot history;
- changing weather derivation, report periods, report membership, generated prose schemas, profile selection, or the provider model ladder;
- changing Distributor's remote API or bundle-content contract;
- deleting or managing operator-owned report and debug outputs;
- a general logging or observability subsystem; or
- live external services in the default test suite.
Safety And Testing Policy
Tests should emphasize observable stateless behavior rather than removed file choreography. Important risks requiring durable offline coverage include:
- a failed or canceled generation truncating or replacing an existing output;
- default paths resolving somewhere other than the invocation working directory;
- Daily output using the wrong valid local date;
- a batch item overwriting another planned output;
- a notification attempt occurring before its report output is complete;
- one batch failure deleting or corrupting another report's successful output;
- summaries exposing nonexistent transient paths;
- temporary files surviving an ordinary success or handled failure;
- default operation recreating a workspace or historical artifact tree; and
- debug capture leaking credentials or being created without explicit opt-in.
Tests remain deterministic, offline, credential-free, and use real temporary directories plus narrow external-boundary fakes. Existing tests whose only purpose is to preserve removed state, metadata, inspection, or Recent Changes contracts should be deleted rather than translated into assertions about private replacement mechanics.
Completion Criteria
The target state is achieved when:
- a clean invocation requires no prior Weatherreporter-created files;
- ordinary runs leave only their selected Markdown outputs;
- omitted output flags resolve to the documented filenames in the current working directory;
- failed and canceled attempts preserve any existing destination file;
- no local prior-run comparison or Recent Changes contract remains;
- no workspace configuration, run-history command, metadata compatibility, or durable intermediate-artifact contract remains;
- Distributor uses only completed current-invocation outputs;
- debug files are created only through explicit secure capture;
- repeated successful and failed runs do not create application-owned history;
- the test suite proves the stateless, atomic-output, batch, notification, and security boundaries offline;
- an Accepted ADR records the architectural decision; and
- canonical current-state documentation describes only the implemented stateless lifecycle.