Plan the stateless execution refactor
This commit is contained in:
@@ -1,39 +1,38 @@
|
|||||||
# Ephemeral Operational State Roadmap
|
# Stateless Execution Roadmap
|
||||||
|
|
||||||
Status: Accepted feature direction; implementation has not started.
|
Status: Accepted.
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
Weatherreporter should treat generated weather reports and their intermediate
|
Weatherreporter should be a stateless report transformation pipeline. Each
|
||||||
artifacts as short-lived operational material rather than a durable audit
|
invocation fetches current inputs from the Weather API, derives deterministic
|
||||||
history. Forecasts and current conditions change continuously, and the normal
|
facts, executes Promptkit, renders Markdown, and writes or distributes the
|
||||||
response to an old or failed report is to generate a new report, not to
|
completed report. It does not retain application-owned history or operational
|
||||||
reconstruct the provenance of the old one.
|
state between invocations.
|
||||||
|
|
||||||
The application should retain only the bounded state needed to publish the
|
Weather reports are ephemeral products rather than business records. Forecasts
|
||||||
current report, calculate Recent Changes against the last successfully
|
and current conditions change continuously, and the normal response to an old
|
||||||
published report for the same valid period, and complete the current
|
or failed report is to generate a new one rather than recover, replay, or
|
||||||
invocation safely. Detailed LLM diagnostics should remain an explicit,
|
inspect the prior generation.
|
||||||
operator-controlled exception outside ordinary workspace state.
|
|
||||||
|
|
||||||
This roadmap defines the intended state lifecycle, compatibility policy, and
|
This roadmap defines the desired lifecycle, output contract, compatibility
|
||||||
architectural boundaries. A separate implementation plan will define the
|
policy, and architectural boundaries.
|
||||||
ordered work after the roadmap is complete.
|
|
||||||
|
|
||||||
## User Intent
|
## User Intent
|
||||||
|
|
||||||
The state model should reflect these product expectations:
|
The target design reflects these product expectations:
|
||||||
|
|
||||||
- weather reports are ephemeral products, not business records;
|
- each invocation is independent and requires no prior Weatherreporter state;
|
||||||
- old report provenance has no continuing operational value once conditions
|
- routine operation creates only the requested report outputs;
|
||||||
and forecasts have changed;
|
- reports are written somewhere useful even when the operator omits an
|
||||||
- regenerating is preferable to recovering, replaying, or inspecting an old
|
explicit output flag;
|
||||||
generation;
|
- Weatherreporter does not maintain forecast history merely to compare runs;
|
||||||
- routine operation should not accumulate unbounded run-addressed artifacts;
|
- regenerating replaces a same-named output atomically instead of creating an
|
||||||
- Recent Changes remains useful, but needs only one prior successful snapshot
|
archive;
|
||||||
for the same report and valid period; and
|
- Distributor receives the completed report produced by the current
|
||||||
- sensitive prompt and response capture remains opt-in and explicitly managed
|
invocation; and
|
||||||
by the operator.
|
- sensitive diagnostics are retained only through an explicit,
|
||||||
|
operator-controlled debug option.
|
||||||
|
|
||||||
## Current State
|
## Current State
|
||||||
|
|
||||||
@@ -41,337 +40,286 @@ Each generation currently writes a run-addressed collection containing a
|
|||||||
module snapshot, data package, prompt preparation receipt, prompt execution
|
module snapshot, data package, prompt preparation receipt, prompt execution
|
||||||
receipt, raw generated text, validated generated text, render context, managed
|
receipt, raw generated text, validated generated text, render context, managed
|
||||||
report, metadata, and optional notification receipt. Successful and failed
|
report, metadata, and optional notification receipt. Successful and failed
|
||||||
runs accumulate beneath the workspace.
|
runs accumulate beneath the configured workspace.
|
||||||
|
|
||||||
Metadata links the collection and supports lookup by RunID. The CLI can list
|
Metadata links these artifacts and supports lookup by RunID. The CLI can list
|
||||||
historical runs and inspect their metadata, modules, data packages, prior
|
historical runs and inspect their metadata, modules, data packages, prior
|
||||||
snapshots, and source provenance. New metadata uses the V2 format while the
|
snapshots, and source provenance. The reader retains V1 compatibility while
|
||||||
reader retains V1 compatibility. Prompt artifacts are validated against
|
new runs write V2 metadata.
|
||||||
current report and prompt definitions when saved and loaded.
|
|
||||||
|
|
||||||
Most of this persistence exists for retrospective inspection and failure
|
Weatherreporter also loads a compatible prior module snapshot for Daily,
|
||||||
recovery. Dedicated prompt preparation and execution load operations have no
|
Today, and Tomorrow and compares it with the current snapshot. Configurable
|
||||||
ordinary production consumer. The important exception is module snapshot
|
thresholds determine whether structured Recent Changes are included in the
|
||||||
state: generation actively loads the most recent compatible snapshot to build
|
Promptkit data package. This is the only current product behavior that depends
|
||||||
the deterministic Recent Changes input for Daily, Today, and Tomorrow.
|
on state from an earlier invocation.
|
||||||
|
|
||||||
## Desired End State
|
## Desired End State
|
||||||
|
|
||||||
Weatherreporter has three distinct state classes:
|
Weatherreporter has no durable application-managed workspace. Its dataflow is:
|
||||||
|
|
||||||
| State class | Lifecycle | Purpose |
|
```text
|
||||||
| --- | --- | --- |
|
Weather API input
|
||||||
| Invocation workspace | Temporary and unpublished | Hold intermediate values while one report or batch is running. |
|
-> deterministic facts and modules
|
||||||
| Current published state | Bounded and replaceable | Hold the current managed report and the minimal deterministic snapshot or manifest needed for normal operation. |
|
-> Promptkit data package and generated text
|
||||||
| Secure LLM debug capture | Explicitly enabled and operator-managed | Diagnose prompt rendering or provider output when the operator deliberately requests sensitive capture. |
|
-> repository-owned Markdown rendering
|
||||||
|
-> operator-owned report output
|
||||||
|
-> optional Distributor upload
|
||||||
|
```
|
||||||
|
|
||||||
Ordinary generation uses an invocation-scoped temporary directory on the same
|
Intermediate values remain in memory wherever practical. A narrowly scoped
|
||||||
filesystem as the managed workspace when atomic publication requires it.
|
temporary file may be used when an external interface requires a file path,
|
||||||
Prompt preparation, prompt execution, raw generated text, validated generated
|
but it exists only for the active invocation and is removed on return.
|
||||||
text, render contexts, data packages, and notification receipts may exist
|
Temporary material is not a supported recovery or inspection surface.
|
||||||
there while needed, but they are not published as durable historical
|
|
||||||
artifacts.
|
|
||||||
|
|
||||||
A successful report atomically replaces the current published state for its
|
RunIDs may remain as in-process correlation identifiers in action summaries,
|
||||||
logical report key and valid period. A failed attempt leaves the last
|
errors, Distributor idempotency values, and explicit debug paths. They do not
|
||||||
successfully published report and comparison snapshot unchanged. Ordinary
|
identify a collection that Weatherreporter can locate or decode later.
|
||||||
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,
|
Configuration files, operator-owned report outputs, and explicitly requested
|
||||||
logs, provider provenance, and optional debug paths. They no longer identify a
|
debug captures are inputs or outputs, not Weatherreporter state.
|
||||||
durable collection that Weatherreporter promises to locate or decode later.
|
|
||||||
|
|
||||||
## Published Report Policy
|
## Report Output Contract
|
||||||
|
|
||||||
The managed Markdown report remains the authoritative upload source during an
|
Every successful report generation writes one operator-owned Markdown output.
|
||||||
invocation. The intended default is to retain only the current managed report
|
An explicit output option selects its destination. When no explicit destination
|
||||||
for each logical report key and valid period, replacing it atomically after a
|
is supplied, Weatherreporter uses the process working directory captured at
|
||||||
new report has been fully rendered and validated.
|
invocation start.
|
||||||
|
|
||||||
An explicit `--out` or `--out-dir` copy remains operator-owned output outside
|
Default single-report filenames are:
|
||||||
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.
|
| Report | Default output |
|
||||||
Notification success or failure does not create a durable notification
|
| --- | --- |
|
||||||
history. A notification failure leaves the newly published report available
|
| Daily | `daily-YYYY-MM-DD.md`, using the report's valid local date |
|
||||||
and returns a safe error through the current action result.
|
| Today | `today.md` |
|
||||||
|
| Tomorrow | `tomorrow.md` |
|
||||||
|
| Hourly | `hourly.md` |
|
||||||
|
|
||||||
## Recent Changes State
|
`--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.
|
||||||
|
|
||||||
Recent Changes must be preserved without preserving general report history.
|
For `run`, `--out-dir PATH` selects the report-output directory and the current
|
||||||
For Daily, Today, and Tomorrow, Weatherreporter retains at most one compatible
|
working directory is the default when it is omitted. Existing batch filenames
|
||||||
module snapshot for each logical report key and valid period.
|
remain: `today.md`, `tomorrow.md`, and `daily-YYYY-MM-DD.md`. Successful items
|
||||||
|
in a partially failed batch retain their outputs.
|
||||||
|
|
||||||
The retained snapshot represents the last successfully published report. A
|
Output publication is atomic. A completed generation may atomically replace an
|
||||||
new invocation reads it before constructing Recent Changes and replaces it
|
existing file at the selected path, but a failed or canceled generation must
|
||||||
only when the new managed report has been successfully validated, rendered,
|
not truncate or partially replace it. Weatherreporter does not rotate, archive,
|
||||||
and published. A failed generation therefore does not become the baseline for
|
expire, or otherwise manage an output after publication.
|
||||||
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
|
The JSON action summary reports the final output path. It does not expose paths
|
||||||
comparison snapshot solely for symmetry. State whose valid period has ended
|
to transient intermediates. `--quiet` continues to suppress the action summary,
|
||||||
and can no longer participate in a supported comparison is eligible for safe
|
not report creation.
|
||||||
cleanup.
|
|
||||||
|
|
||||||
## Temporary Workspace And Failure Semantics
|
## Distributor Contract
|
||||||
|
|
||||||
Temporary state must remain beneath a narrowly owned application directory and
|
Distributor uploads use the completed Markdown output from the active
|
||||||
use safe path construction, restrictive permissions where content is
|
invocation. There is no separate durable managed-report copy and no workspace
|
||||||
sensitive, and atomic writes where practical. Publication must not expose a
|
scan.
|
||||||
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
|
For a single report, local output publication completes before notification.
|
||||||
that remain meaningful after the command: a previously or newly published
|
A notification failure leaves the report output intact and returns a safe
|
||||||
report, an explicit operator output, or an enabled secure debug capture.
|
error through the active result. It does not create a notification receipt.
|
||||||
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
|
Batches continue to suppress per-report notification and attempt their
|
||||||
directory is never considered published state, is never selected for Recent
|
batch-level upload only after every planned report succeeds. A report failure
|
||||||
Changes, and may be removed by a documented safe cleanup mechanism. Cleanup
|
leaves other successful output files intact, skips the batch upload, and
|
||||||
must distinguish inactive temporary directories from concurrent active
|
returns an aggregate failure. Distributor status remains active-workflow
|
||||||
invocations and must never recursively target the workspace root or an
|
information rather than retained Weatherreporter history.
|
||||||
unresolved configuration path.
|
|
||||||
|
|
||||||
## Inspection And Metadata Policy
|
## Recent Changes Deprecation And Removal
|
||||||
|
|
||||||
Run-history discovery and inspection are not part of the desired product
|
The local Recent Changes feature is deprecated by this accepted direction and
|
||||||
contract. The historical `inspect reports`, `inspect metadata`, `inspect
|
is removed when the stateless execution change lands. Its low practical value
|
||||||
modules`, `inspect data-package`, `inspect prior`, and `inspect sources`
|
does not justify retaining a historical state subsystem.
|
||||||
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
|
Removal includes:
|
||||||
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
|
- prior-snapshot discovery and compatibility rules;
|
||||||
state. A new release may replace or ignore incompatible current-state files,
|
- the `internal/changes` comparison implementation;
|
||||||
provided it fails safely, never mistakes stale state for a compatible Recent
|
- report-registry comparison strategies and compatible-prior declarations;
|
||||||
Changes baseline, and documents any operator action required during upgrade.
|
- `recent_change` configuration and threshold validation;
|
||||||
|
- Recent Changes values in application results, prompt inputs, fixtures, and
|
||||||
|
tests;
|
||||||
|
- the `recent_changes` Promptkit data-package stanza; and
|
||||||
|
- prompt instructions that refer to supplied recent changes.
|
||||||
|
|
||||||
## Prompt Execution And Debugging
|
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](future.md#upstream-forecast-change-product) and is
|
||||||
|
not a prerequisite for this refactor.
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
Prompt inspection before weather collection and prepared execution remain
|
Prompt inspection before weather collection and prepared execution remain
|
||||||
runtime safety requirements. They do not require durable preparation or
|
runtime safety requirements. Preparation details, effective profile and model,
|
||||||
execution receipts.
|
validation outcomes, source warnings, and safe errors remain available to the
|
||||||
|
active workflow and its action summary where useful.
|
||||||
|
|
||||||
The selected logical profile, effective backend and model, validation outcome,
|
The existing `--llm-debug-dir PATH` option remains the explicit exception to
|
||||||
and safe classified error remain available to the active workflow and its CLI
|
stateless output. When supplied, it may retain rendered prompts, schemas, input
|
||||||
summary where useful. Weatherreporter does not retain them as long-term report
|
bodies, generated bodies, and effective parameters according to its secure
|
||||||
provenance after the invocation completes.
|
capture contract. The operator selects and manages that location;
|
||||||
|
Weatherreporter does not clean or archive it. Credentials remain excluded.
|
||||||
|
|
||||||
The existing explicit secure debug root remains outside ordinary state and may
|
Adding a broader logging framework or an implicit persistent debug directory
|
||||||
retain rendered prompts, schemas, input bodies, generated bodies, and effective
|
is outside this feature. A future rename or generalization to `--debug` should
|
||||||
parameters according to its documented contract. Weatherreporter does not
|
be considered separately so this state refactor does not expand the sensitive
|
||||||
automatically clean that operator-selected location. Credentials must remain
|
capture contract incidentally.
|
||||||
excluded from debug capture.
|
|
||||||
|
## Removed State And Inspection Contracts
|
||||||
|
|
||||||
|
The target removes:
|
||||||
|
|
||||||
|
- the `workspace` configuration 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`, and `inspect 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
|
## Compatibility And Upgrade Policy
|
||||||
|
|
||||||
This is an intentional breaking change to the workspace and inspection
|
This is an intentional breaking change to the CLI, configuration, prompt-input,
|
||||||
contracts. Weatherreporter does not need to migrate historical V1 or V2
|
workspace, and inspection contracts. Weatherreporter does not migrate old V1
|
||||||
metadata, prompt receipts, intermediate generated-text artifacts, or managed
|
or V2 metadata or other historical artifacts.
|
||||||
reports into the new representation.
|
|
||||||
|
|
||||||
Legacy workspace trees must not be silently interpreted as current published
|
Legacy workspace trees are ignored. Weatherreporter must not discover,
|
||||||
state. They also must not be deleted automatically merely because a new
|
interpret, or automatically delete them. Release notes and operations
|
||||||
version starts: an operator may have placed or referenced files there despite
|
documentation identify the obsolete configuration and commands and provide a
|
||||||
the absence of a continuing application compatibility promise. Release notes
|
precise manual cleanup procedure for operators who want to remove the legacy
|
||||||
and operations documentation must explain whether legacy data can be removed
|
workspace.
|
||||||
manually and identify the exact safe target.
|
|
||||||
|
|
||||||
The change should land in a release whose notes clearly identify removed CLI
|
Existing report files explicitly written through `--out` or `--out-dir` remain
|
||||||
commands, obsolete paths and schemas, the new bounded state behavior, and any
|
operator-owned and are never treated as legacy workspace material.
|
||||||
upgrade action. Because Weatherreporter remains pre-1.0, the ordinary semantic
|
|
||||||
version policy may carry this breaking change without inventing a migration
|
The change should land in a release whose notes identify the removed Recent
|
||||||
framework.
|
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
|
## Required Architecture Decision Record
|
||||||
|
|
||||||
The implemented feature must include an Accepted ADR recording the durable
|
The target state includes an Accepted ADR recording the durable decision to
|
||||||
architectural decision to use ephemeral operational state. The ADR is not part
|
make Weatherreporter stateless.
|
||||||
of this roadmap-writing pass and should not be created until implementation is
|
|
||||||
being prepared.
|
|
||||||
|
|
||||||
The ADR should record:
|
The ADR should record:
|
||||||
|
|
||||||
- the mismatch between run-addressed provenance storage and the ephemeral
|
- the mismatch between run-addressed provenance storage and ephemeral weather
|
||||||
weather-report lifecycle;
|
reports;
|
||||||
- the decision to retain bounded current report and comparison state rather
|
- the decision to remove local change detection rather than retain state for a
|
||||||
than historical runs;
|
rarely used report section;
|
||||||
- the distinction between temporary invocation state, published operational
|
- the transformation-pipeline model and operator-owned output boundary;
|
||||||
state, explicit output copies, and secure debug capture;
|
- the absence of historical inspection and backward-compatibility guarantees;
|
||||||
- the removal of historical inspection and backward-compatibility guarantees;
|
- atomic output and failure behavior;
|
||||||
- atomic publication and failed-run behavior;
|
- the separation of explicit debug capture from ordinary execution;
|
||||||
- the alternatives considered, including retaining the current archive,
|
- the upstream-service path for any future forecast comparison; and
|
||||||
adding time-based retention, or keeping a bounded run history; and
|
- alternatives considered, including the former bounded-current-state design,
|
||||||
- consequences for CLI compatibility, workspace layout, testing, operations,
|
time-based retention, and a bounded run history.
|
||||||
and future schema changes.
|
|
||||||
|
|
||||||
Once accepted, the ADR owns the decision rationale. The architecture policy
|
Once accepted, the ADR owns the rationale. Architecture owns the resulting
|
||||||
owns the resulting current invariant, while focused state, CLI, operations,
|
stateless invariant, while CLI, operations, configuration, integrations, and
|
||||||
and integration documents own the implemented contracts.
|
focused internal documents own implemented contracts.
|
||||||
|
|
||||||
## Scope
|
## Scope
|
||||||
|
|
||||||
The completed feature includes:
|
The completed feature includes:
|
||||||
|
|
||||||
- an invocation-scoped temporary workspace for intermediate generation state;
|
- removal of local Recent Changes and all prior-run dependencies;
|
||||||
- atomic publication of the current managed report and its minimal operational
|
- removal of the durable workspace, artifact persistence, metadata
|
||||||
state;
|
compatibility, and historical inspection surfaces;
|
||||||
- a bounded comparison snapshot representing the last successfully published
|
- in-memory or invocation-temporary processing with safe cleanup;
|
||||||
report for each supported report key and valid period;
|
- atomic operator-owned output for every successful report;
|
||||||
- safe cleanup behavior for normal completion, handled failure, and abandoned
|
- current-working-directory defaults and explicit output overrides;
|
||||||
temporary workspaces;
|
- preservation of report generation, batch membership, Promptkit execution,
|
||||||
- removal of durable prompt preparation, prompt execution, generated-text,
|
Distributor delivery, action summaries, and opt-in secure debug capture;
|
||||||
render-context, data-package, notification, and run-metadata history;
|
- removal or simplification of state-only packages, fields, configuration,
|
||||||
- removal of run-history inspection commands and their application/state
|
fixtures, tests, and documentation;
|
||||||
contracts;
|
- exact-version prompt updates for the breaking input-contract change;
|
||||||
- removal of V1 metadata compatibility and current-version coupling for
|
- deterministic offline tests for output atomicity, failure isolation, default
|
||||||
historical prompt artifacts by removing the historical artifact contract;
|
path selection, Distributor sequencing, and absence of durable state;
|
||||||
- preservation of active-command partial status, safe errors, and paths to
|
- an Accepted ADR documenting the decision; and
|
||||||
genuinely retained published, operator-owned, or debug outputs;
|
- canonical documentation describing the implemented contract and clear
|
||||||
- preservation of explicit output copies, Distributor upload behavior, and
|
release-note requirements for the release that publishes it.
|
||||||
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,
|
|
||||||
integration, internal, testing, and release documentation
|
|
||||||
where their contracts change.
|
|
||||||
|
|
||||||
## Non-Goals
|
## Non-Goals
|
||||||
|
|
||||||
This feature does not include:
|
This feature does not include:
|
||||||
|
|
||||||
- a general-purpose cache, database, archival service, or retention engine;
|
- the future upstream forecast-change API or reintroduced change commentary;
|
||||||
- replaying or resuming interrupted generation;
|
- a cache, database, archive, retention engine, manifest, or resume mechanism;
|
||||||
- migrating legacy artifacts into the new representation;
|
- migration or automatic deletion of legacy workspace artifacts;
|
||||||
- retaining a bounded number of historical runs for convenience;
|
- retaining a bounded report or snapshot history;
|
||||||
- automatic upload or archival of state to remote storage;
|
- changing weather derivation, report periods, report membership, generated
|
||||||
- collecting additional provider telemetry or weather-source provenance;
|
prose schemas, profile selection, or the provider model ladder;
|
||||||
- changing report content, prompt text, schemas, profile selection, weather
|
- changing Distributor's remote API or bundle-content contract;
|
||||||
derivation, or batch membership;
|
- deleting or managing operator-owned report and debug outputs;
|
||||||
- deleting operator-owned `--out`, `--out-dir`, or secure debug files;
|
- a general logging or observability subsystem; or
|
||||||
- changing Distributor's report-content contract; or
|
- live external services in the default test suite.
|
||||||
- making live external services part of the default test suite.
|
|
||||||
|
|
||||||
## Safety And Testing Policy
|
## Safety And Testing Policy
|
||||||
|
|
||||||
The state refactoring must preserve Weatherreporter's existing path-safety and
|
Tests should emphasize observable stateless behavior rather than removed file
|
||||||
atomicity expectations while reducing the amount of durable state. Tests
|
choreography. Important risks requiring durable offline coverage include:
|
||||||
should emphasize observable lifecycle guarantees rather than private 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.
|
||||||
|
|
||||||
- a failed or canceled generation replacing a previously published report or
|
Tests remain deterministic, offline, credential-free, and use real temporary
|
||||||
comparison baseline;
|
directories plus narrow external-boundary fakes. Existing tests whose only
|
||||||
- a partially written report becoming visible as current;
|
purpose is to preserve removed state, metadata, inspection, or Recent Changes
|
||||||
- Recent Changes selecting an incompatible report, valid period, or failed
|
contracts should be deleted rather than translated into assertions about
|
||||||
attempt;
|
private replacement mechanics.
|
||||||
- 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 implemented domain-specific profiles do not add historical compatibility
|
|
||||||
or durable-provenance commitments. Profile inspection, selection, override
|
|
||||||
precedence, and effective model resolution remain active-workflow behavior and
|
|
||||||
survive the state change. Existing prompt artifacts need not remain readable
|
|
||||||
after this refactor and must not constrain the target architecture.
|
|
||||||
|
|
||||||
## Completion Criteria
|
## Completion Criteria
|
||||||
|
|
||||||
The roadmap's target state is achieved when:
|
The target state is achieved when:
|
||||||
|
|
||||||
- ordinary runs no longer create durable run-addressed artifact collections;
|
- a clean invocation requires no prior Weatherreporter-created files;
|
||||||
- a successful report atomically replaces only the corresponding current
|
- ordinary runs leave only their selected Markdown outputs;
|
||||||
published state;
|
- omitted output flags resolve to the documented filenames in the current
|
||||||
- failed and canceled attempts leave the prior published report and Recent
|
working directory;
|
||||||
Changes baseline unchanged;
|
- failed and canceled attempts preserve any existing destination file;
|
||||||
- Daily, Today, and Tomorrow compare against at most one compatible snapshot
|
- no local prior-run comparison or Recent Changes contract remains;
|
||||||
from the last successfully published report;
|
- no workspace configuration, run-history command, metadata compatibility, or
|
||||||
- expired comparison and published state can be removed safely without
|
durable intermediate-artifact contract remains;
|
||||||
touching operator-owned or active files;
|
- Distributor uses only completed current-invocation outputs;
|
||||||
- Hourly does not retain an unused comparison snapshot;
|
- debug files are created only through explicit secure capture;
|
||||||
- historical inspection commands and V1/V2 archival compatibility code are
|
- repeated successful and failed runs do not create application-owned history;
|
||||||
removed;
|
- the test suite proves the stateless, atomic-output, batch, notification, and
|
||||||
- temporary, published, explicit-output, and debug paths have distinct and
|
security boundaries offline;
|
||||||
documented ownership and cleanup rules;
|
- an Accepted ADR records the architectural decision; and
|
||||||
- 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
|
- canonical current-state documentation describes only the implemented
|
||||||
lifecycle.
|
stateless 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.
|
|
||||||
|
|||||||
@@ -3,6 +3,40 @@
|
|||||||
This roadmap contains future work only. Each section identifies its planning
|
This roadmap contains future work only. Each section identifies its planning
|
||||||
status; current behavior is documented outside `docs/roadmap/`.
|
status; current behavior is documented outside `docs/roadmap/`.
|
||||||
|
|
||||||
|
## Upstream Forecast Change Product
|
||||||
|
|
||||||
|
Status: Proposed upstream feature request; unimplemented.
|
||||||
|
|
||||||
|
Weatherreporter's local Recent Changes feature is deprecated for removal by
|
||||||
|
the accepted [stateless execution roadmap](ephemeral-state.md). Forecast
|
||||||
|
version history and comparison are better owned by the Weather API, where the
|
||||||
|
underlying forecast issuances can be retained and compared consistently for
|
||||||
|
all consumers.
|
||||||
|
|
||||||
|
A future Weather API feature should expose a structured change product with:
|
||||||
|
|
||||||
|
- explicit current and baseline forecast issuance timestamps or identifiers;
|
||||||
|
- documented baseline selection, such as a requested comparison timestamp,
|
||||||
|
preceding issuance, or fixed rolling period;
|
||||||
|
- location, timezone, and half-open valid-period identity;
|
||||||
|
- typed changed values with previous and current values and units;
|
||||||
|
- stable change categories for temperature, precipitation probability and
|
||||||
|
timing, wind gusts, alerts, and aggregate hazards;
|
||||||
|
- an API-owned significance classification or enough structured information
|
||||||
|
for a stateless consumer to apply a documented presentation threshold; and
|
||||||
|
- deterministic ordering, missing-baseline behavior, and source metadata.
|
||||||
|
|
||||||
|
The API should compare forecast versions, not track a Weatherreporter client's
|
||||||
|
"previous run." It should not require consumer identity, mutable cursors, or
|
||||||
|
Weatherreporter-managed history. A missing baseline should be a normal empty
|
||||||
|
result rather than an error.
|
||||||
|
|
||||||
|
Once a stable upstream contract exists, a separate Weatherreporter roadmap may
|
||||||
|
reintroduce change commentary by collecting that product and mapping it into a
|
||||||
|
curated prompt-facing module. There must be no local snapshot fallback. The
|
||||||
|
ordinary Weatherreporter process must remain stateless, and the upstream
|
||||||
|
feature should have deterministic fixtures before adoption.
|
||||||
|
|
||||||
## Automatic Storm Monitoring
|
## Automatic Storm Monitoring
|
||||||
|
|
||||||
Status: Proposed and unimplemented.
|
Status: Proposed and unimplemented.
|
||||||
@@ -14,7 +48,9 @@ Possible direction:
|
|||||||
1. Detect candidate storm events from alerts, forecast discussion, weather
|
1. Detect candidate storm events from alerts, forecast discussion, weather
|
||||||
story context, hourly thresholds, and material forecast changes.
|
story context, hourly thresholds, and material forecast changes.
|
||||||
2. Evaluate candidates through Promptkit or another narrow evaluator adapter.
|
2. Evaluate candidates through Promptkit or another narrow evaluator adapter.
|
||||||
3. Persist storm lifecycle state.
|
3. Keep any required storm lifecycle state in the upstream service or another
|
||||||
|
explicitly designed external owner rather than silently reintroducing a
|
||||||
|
Weatherreporter workspace.
|
||||||
4. Generate or update a storm report only when a meaningful event is present.
|
4. Generate or update a storm report only when a meaningful event is present.
|
||||||
5. Suppress ordinary low-impact thunder or rain chances.
|
5. Suppress ordinary low-impact thunder or rain chances.
|
||||||
|
|
||||||
@@ -54,8 +90,7 @@ Status: Proposed and unimplemented.
|
|||||||
Possible future modules:
|
Possible future modules:
|
||||||
|
|
||||||
- `hourly_table` for compact valid-period hourly facts
|
- `hourly_table` for compact valid-period hourly facts
|
||||||
- `forecast_delta` if a separate stanza is useful beyond current Recent
|
- `forecast_delta` after an upstream forecast-change product exists
|
||||||
Changes
|
|
||||||
- `weekend_planning` if weekend-specific planning guidance needs a dedicated
|
- `weekend_planning` if weekend-specific planning guidance needs a dedicated
|
||||||
deterministic stanza
|
deterministic stanza
|
||||||
- `storm_window_summary` if manual or automatic storm reports need a dedicated
|
- `storm_window_summary` if manual or automatic storm reports need a dedicated
|
||||||
@@ -79,7 +114,7 @@ contracts](../internal/facts.md), [module internals](../internal/module.md), and
|
|||||||
- keep broad reusable calculations in `DerivedFacts`
|
- keep broad reusable calculations in `DerivedFacts`
|
||||||
- keep prompt-facing field shape inside module builders
|
- keep prompt-facing field shape inside module builders
|
||||||
- use typed options for configurable module behavior
|
- use typed options for configurable module behavior
|
||||||
- keep module snapshots structured and deterministic for Recent Changes
|
- keep module output structured and deterministic
|
||||||
|
|
||||||
## Distributor Notification Enhancements
|
## Distributor Notification Enhancements
|
||||||
|
|
||||||
@@ -92,10 +127,8 @@ behavior is documented in the [Distributor adapter guide](../internal/distributo
|
|||||||
unimplemented:
|
unimplemented:
|
||||||
|
|
||||||
- `failure_policy: warn`
|
- `failure_policy: warn`
|
||||||
- uploading metadata, module snapshots, data packages, or preflight artifacts
|
|
||||||
- durable upload retry queues
|
- durable upload retry queues
|
||||||
- distributor-specific CLI flags
|
- distributor-specific CLI flags
|
||||||
- distributor workspace scanning
|
|
||||||
- destination routing, Markdown-to-HTML transformation, public URLs, or nginx
|
- destination routing, Markdown-to-HTML transformation, public URLs, or nginx
|
||||||
layout inside weatherreporter
|
layout inside weatherreporter
|
||||||
|
|
||||||
@@ -138,6 +171,7 @@ maintenance costs make the added abstraction worthwhile:
|
|||||||
- global test helper package
|
- global test helper package
|
||||||
- logging subsystem
|
- logging subsystem
|
||||||
|
|
||||||
Any future implementation should preserve the existing public CLI, artifact
|
Any future implementation should preserve the public CLI, report-output
|
||||||
paths, report identities, module boundaries, and adapter boundaries unless a
|
contract, report identities, module boundaries, and adapter boundaries in
|
||||||
separate roadmap explicitly changes them.
|
effect when that work begins unless a separate roadmap explicitly changes
|
||||||
|
them.
|
||||||
|
|||||||
739
docs/roadmap/implementation.md
Normal file
739
docs/roadmap/implementation.md
Normal file
@@ -0,0 +1,739 @@
|
|||||||
|
# Stateless Execution Implementation Plan
|
||||||
|
|
||||||
|
Status: Ready for implementation.
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
This plan implements the accepted [Stateless Execution
|
||||||
|
Roadmap](ephemeral-state.md). That roadmap is authoritative for product intent,
|
||||||
|
policy choices, and the desired end state. This document owns implementation
|
||||||
|
order, concrete code changes, and verification gates.
|
||||||
|
|
||||||
|
The target is a Weatherreporter process whose ordinary invocations require no
|
||||||
|
prior application state and leave only operator-owned Markdown outputs. Local
|
||||||
|
Recent Changes, the managed workspace, historical artifacts and metadata, and
|
||||||
|
the `inspect` command family are removed. Explicit secure Promptkit debug
|
||||||
|
capture remains operator-owned.
|
||||||
|
|
||||||
|
## Implementation Rules
|
||||||
|
|
||||||
|
1. Implement the stages in numeric order. Do not merge or release an
|
||||||
|
intermediate stage as a completed stateless-execution feature.
|
||||||
|
2. Keep the repository buildable and `go test ./...` passing at every stage.
|
||||||
|
Use focused tests while iterating, then run the stage's listed commands.
|
||||||
|
3. Follow the architecture, documentation, and testing policies under
|
||||||
|
`docs/policy/`. Delete tests that protect intentionally removed contracts;
|
||||||
|
do not mechanically rewrite them to preserve obsolete structures.
|
||||||
|
4. Do not retain compatibility shims for `workspace`, `recent_change`,
|
||||||
|
historical metadata, inspection commands, prompt artifact paths, or the
|
||||||
|
`recent_changes` prompt field. Strict configuration loading should reject
|
||||||
|
removed fields.
|
||||||
|
5. Preserve prompt inspection before weather collection, batch-wide prompt
|
||||||
|
inspection before collection, exact profile selection, structured-output
|
||||||
|
validation, repository-owned rendering, deterministic report periods,
|
||||||
|
batch membership, safe error classification, and Distributor bundle paths.
|
||||||
|
6. Preserve the existing `--llm-debug-dir PATH` interface and security
|
||||||
|
properties. Do not introduce an implicit debug location or a general
|
||||||
|
logging subsystem.
|
||||||
|
7. Do not contact live Weather API, Promptkit provider, or Distributor
|
||||||
|
services in repository tests.
|
||||||
|
8. Do not create release notes until a release version is selected. The
|
||||||
|
durable documentation stage must record the compatibility and operator
|
||||||
|
actions that future release notes need to summarize.
|
||||||
|
|
||||||
|
## Target Contracts
|
||||||
|
|
||||||
|
These decisions are fixed for implementation:
|
||||||
|
|
||||||
|
- `generate` always writes exactly one operator-owned Markdown file.
|
||||||
|
- `--out PATH` selects that file. Without `--out`, the destination is in the
|
||||||
|
working directory captured at invocation start:
|
||||||
|
`daily-YYYY-MM-DD.md`, `today.md`, `tomorrow.md`, or `hourly.md`.
|
||||||
|
- `run` writes each successful report beneath `--out-dir PATH`, or beneath the
|
||||||
|
captured working directory when the flag is omitted. Daily batch filenames
|
||||||
|
remain date-qualified.
|
||||||
|
- CLI-resolved output paths are cleaned absolute paths. App-level action
|
||||||
|
requests receive an absolute working directory plus an optional operator
|
||||||
|
override and reject invalid or empty resolved destinations before weather
|
||||||
|
collection.
|
||||||
|
- A generation publishes its selected output atomically. Failure or
|
||||||
|
cancellation before publication leaves an existing destination unchanged.
|
||||||
|
- Single-report notification occurs after local output publication. Batch
|
||||||
|
notification occurs only after every planned report succeeds. Distributor
|
||||||
|
reads the selected output files; there is no second managed copy.
|
||||||
|
- Action summaries retain identity, valid period, safe effective
|
||||||
|
profile/backend/model information, source warnings, final output path,
|
||||||
|
optional debug path, notification status, and a safe error. They contain no
|
||||||
|
historical or transient artifact paths.
|
||||||
|
- RunIDs remain active correlation and idempotency values only.
|
||||||
|
- The prompt data-package schema becomes
|
||||||
|
`weatherreporter.data_package.v4`, with no `recent_changes` member. All four
|
||||||
|
embedded prompts become exact version `2.0.0`.
|
||||||
|
- Ordinary execution creates no `workspace` tree, metadata, receipts,
|
||||||
|
snapshots, data packages, generated-text intermediates, render-context
|
||||||
|
files, notification artifacts, or run index.
|
||||||
|
|
||||||
|
## Stage 1: Record The Stateless Architecture Decision
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Create the durable decision record before changing the architecture, without
|
||||||
|
describing unimplemented behavior as current behavior elsewhere.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Create `docs/adr/` if it does not exist and add
|
||||||
|
`docs/adr/0001-stateless-execution.md` as an Accepted ADR using the format
|
||||||
|
required by `docs/policy/documentation.md`.
|
||||||
|
2. Record:
|
||||||
|
- why run-addressed provenance conflicts with ephemeral weather reports;
|
||||||
|
- removal of local Recent Changes rather than retention of state for it;
|
||||||
|
- the stateless transformation pipeline and operator-owned output boundary;
|
||||||
|
- atomic output and notification ordering;
|
||||||
|
- explicit debug capture as the only retained diagnostic-file exception;
|
||||||
|
- removal of inspection and backward-compatible workspace decoding;
|
||||||
|
- the upstream Weather API path for future forecast comparison; and
|
||||||
|
- alternatives: the former bounded-current-state design, time-based
|
||||||
|
retention, and bounded run history.
|
||||||
|
3. Link the ADR to the feature roadmap for scope, while keeping the ADR focused
|
||||||
|
on durable rationale rather than implementation stages.
|
||||||
|
4. Do not update current-state architecture or user documentation in this
|
||||||
|
stage.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify every repository-relative ADR link resolves.
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
An Accepted ADR records the exact decision and consequences; no production
|
||||||
|
behavior or current-state documentation has changed.
|
||||||
|
|
||||||
|
## Stage 2: Remove Recent Changes From The Prompt Contract
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Stop generating or sending local comparison results while the existing
|
||||||
|
workspace remains temporarily available for unrelated artifacts.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Remove `RecentChanges` from `promptinput.BuildRequest` and
|
||||||
|
`promptinput.Package`, delete the prompt-input `RecentChanges` wrapper, and
|
||||||
|
remove the `internal/changes` dependency from `internal/promptinput`.
|
||||||
|
2. Advance `promptinput.SchemaVersion` from
|
||||||
|
`weatherreporter.data_package.v3` to `weatherreporter.data_package.v4`.
|
||||||
|
Update marshal, load, validation, round-trip, ordering, and fixture tests so
|
||||||
|
v4 has no `recent_changes` key and v3 is rejected.
|
||||||
|
3. In app orchestration, stop finding a prior snapshot, loading it, invoking a
|
||||||
|
comparator, or placing Recent Changes in `ReportResult` or prompt input.
|
||||||
|
Continue building the current module snapshot because it is still needed
|
||||||
|
in memory for prompt input and rendering, and may still be persisted by the
|
||||||
|
transitional workflow.
|
||||||
|
4. Remove Recent Changes fields and assertions from app workflow fakes and
|
||||||
|
tests. Delete prior-run workflow cases whose only purpose was local change
|
||||||
|
detection.
|
||||||
|
5. Change all four report-definition prompt versions and embedded prompt YAML
|
||||||
|
versions from `1.1.0` to `2.0.0`.
|
||||||
|
6. Remove the common system-prompt reference to supplied recent changes.
|
||||||
|
Review every prompt body to ensure none instructs the model to infer or
|
||||||
|
discuss changes from an absent comparison field.
|
||||||
|
7. Update prompt-asset and adapter integration fixtures to use exact version
|
||||||
|
`2.0.0`. Do not change generated-text output schemas or report templates;
|
||||||
|
neither directly depends on Recent Changes.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./internal/promptinput ./internal/promptassets ./internal/report
|
||||||
|
go test ./internal/app ./internal/adapters/promptkit
|
||||||
|
go test ./...
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
Add or retain focused tests proving that serialized v4 packages omit
|
||||||
|
`recent_changes` entirely and every embedded prompt resolves at `2.0.0`.
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
No generated prompt package or active app workflow contains Recent Changes,
|
||||||
|
while report generation and the still-transitional persistence workflow
|
||||||
|
continue to function.
|
||||||
|
|
||||||
|
## Stage 3: Delete Dormant Local Comparison Policy
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Remove comparison code and configuration that no active report workflow uses.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Delete `internal/changes` and its tests.
|
||||||
|
2. Remove `RecentChangeConfig`, `Config.RecentChange`, its defaults,
|
||||||
|
validation, YAML handling, test fixtures, and maintained example values.
|
||||||
|
3. Add a strict-loading regression test showing that a top-level
|
||||||
|
`recent_change:` stanza is now rejected as unknown. Do not silently ignore
|
||||||
|
the obsolete field.
|
||||||
|
4. Remove stale Recent Changes imports, helpers, test builders, and comments
|
||||||
|
throughout app, config, prompt input, facts, forecast, briefing, generated
|
||||||
|
text, and report code.
|
||||||
|
5. Leave report comparison declarations and state prior-lookup code only where
|
||||||
|
the still-supported historical `inspect prior` path requires them. They are
|
||||||
|
removed with inspection in Stage 8; do not invent a new consumer.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./internal/config ./internal/app ./internal/promptinput
|
||||||
|
go test ./...
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
No active generation code or configuration surface implements local change
|
||||||
|
detection, and the legacy field fails strict configuration loading.
|
||||||
|
|
||||||
|
## Stage 4: Establish The Operator-Owned Output Contract
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Make every successful action select and atomically write its final output even
|
||||||
|
while the old managed workspace still exists behind the workflow.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Add an injectable `WorkingDir string` to `cli.Runner`. When empty,
|
||||||
|
production calls `os.Getwd` once per action; tests supply an absolute
|
||||||
|
temporary directory without calling `os.Chdir`.
|
||||||
|
2. Pass the captured absolute working directory through `GenerateRequest` and
|
||||||
|
`BatchRequest`. Resolve relative `--out` and `--out-dir` values against it
|
||||||
|
and clean the resulting absolute paths.
|
||||||
|
3. Centralize output filenames rather than duplicating them in CLI and app:
|
||||||
|
- Daily uses `daily-YYYY-MM-DD.md` with the resolved valid-period start in
|
||||||
|
the effective report timezone;
|
||||||
|
- Today, Tomorrow, and Hourly use `today.md`, `tomorrow.md`, and
|
||||||
|
`hourly.md`;
|
||||||
|
- dynamic Daily batch items use the same date-qualified rule.
|
||||||
|
Rename `report.Definition.BatchOutputName` to `OutputName` and rename
|
||||||
|
app-internal “output copy” fields/helpers to “output” terminology. Preserve
|
||||||
|
the external Distributor template variable `batch_output_name` and populate
|
||||||
|
it from the selected output filename.
|
||||||
|
4. When `--out` is absent, resolve the single-report default after the report
|
||||||
|
period is known. When `--out-dir` is absent, use the captured working
|
||||||
|
directory for all batch items.
|
||||||
|
5. Require a non-empty absolute final output path before collection. Reject a
|
||||||
|
filesystem root or a destination that resolves to a directory. Let atomic
|
||||||
|
publication create missing parent directories for a valid file path.
|
||||||
|
6. Continue using `fileutil.WriteFileAtomic` or an equivalently narrow helper.
|
||||||
|
An existing destination may be replaced only after the complete new report
|
||||||
|
has been written and closed successfully.
|
||||||
|
7. Change help and flag descriptions so `--out` and `--out-dir` select report
|
||||||
|
destinations rather than “extra copies.”
|
||||||
|
8. Update app and CLI tests for defaults, explicit absolute and relative
|
||||||
|
overrides, Daily date naming, batch naming, existing-file preservation on
|
||||||
|
failure, and absolute summary paths.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./internal/report ./internal/fileutil
|
||||||
|
go test ./internal/app ./internal/cli
|
||||||
|
go test ./...
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
Every successful single or batch item has one selected operator output path,
|
||||||
|
omitted flags use the captured working directory, and failed publication
|
||||||
|
cannot corrupt an existing destination.
|
||||||
|
|
||||||
|
## Stage 5: Separate Explicit Debug Capture From State
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Preserve secure opt-in Promptkit diagnostics without retaining a dependency on
|
||||||
|
the package that owns the obsolete workspace.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Move `internal/state/debug_writer.go` and its focused tests to
|
||||||
|
`internal/promptdebug`. Move rather than duplicate the implementation.
|
||||||
|
2. Preserve:
|
||||||
|
- empty-path disablement without filesystem access;
|
||||||
|
- absolute non-root destination validation;
|
||||||
|
- safe report/date/RunID path segments;
|
||||||
|
- directory mode `0700` and file mode `0600`;
|
||||||
|
- endpoint sanitization and parameter redaction;
|
||||||
|
- credential exclusion; and
|
||||||
|
- preparation-callback failure preventing provider execution.
|
||||||
|
3. Update app imports and debug tests to use the new package. Do not move
|
||||||
|
ordinary artifacts into the debug package.
|
||||||
|
4. Leave the transitional `DataPackagePath` execution fields intact while
|
||||||
|
persisted receipts still validate them. Stage 7 removes those fields with
|
||||||
|
their final consumer.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./internal/promptdebug ./internal/promptexec
|
||||||
|
go test ./internal/adapters/promptkit ./internal/app ./internal/cli
|
||||||
|
go test ./...
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
Debug capture is independent of `internal/state`, and its security and
|
||||||
|
preparation-callback behavior are unchanged.
|
||||||
|
|
||||||
|
## Stage 6: Remove Notification Persistence
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Make Distributor delivery an active-workflow result that consumes final output
|
||||||
|
files and writes no Weatherreporter receipt.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Refactor `notifyReport` and `notifyBatch` so they do not accept a
|
||||||
|
`state.Store` and do not call any `SaveDistributorNotification` operation.
|
||||||
|
Delete notification-artifact conversion and persistence helpers from app.
|
||||||
|
2. For single reports, build the notification request from the resolved report
|
||||||
|
identity, active RunID/timestamps, and selected `OutputPath`. Remove
|
||||||
|
“managed report” terminology from code and safe errors.
|
||||||
|
3. For batches, use each successful item's `OutputPath` as the Distributor
|
||||||
|
source. Preserve bundle-path rendering, duplicate bundle-path rejection,
|
||||||
|
batch inclusion metadata, all-success gating, and one batch upload.
|
||||||
|
4. Remove `NotificationPath` and batch notification `Path` fields from app
|
||||||
|
results and CLI summaries. Preserve remote run, pipeline, bundle,
|
||||||
|
idempotency, status, timing, and safe-error fields.
|
||||||
|
5. Preserve ordering:
|
||||||
|
- local atomic publication precedes a single notification;
|
||||||
|
- a notification failure leaves the output and returns a failure;
|
||||||
|
- batch notification is skipped after any report failure;
|
||||||
|
- successful batch items remain successful when only batch notification
|
||||||
|
fails.
|
||||||
|
6. Delete tests that assert notification receipt files. Replace them with
|
||||||
|
focused interaction tests proving source paths, ordering, skip behavior,
|
||||||
|
one-call behavior, and failure propagation.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./internal/app ./internal/adapters/distributor
|
||||||
|
go test ./internal/cli
|
||||||
|
go test ./...
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
Distributor behavior uses operator outputs and returns active status without
|
||||||
|
creating notification artifacts or depending on state.
|
||||||
|
|
||||||
|
## Stage 7: Replace The Persisted Generation Workflow
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Convert the shared single-report generation path into a state-free in-memory
|
||||||
|
pipeline used by both `generate` and `run`.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Replace the persistence-oriented `promptReportWorkflow` with a cohesive
|
||||||
|
workflow that:
|
||||||
|
- initializes a safe partial `ReportResult` from `report.Resolved`;
|
||||||
|
- builds collected and derived facts;
|
||||||
|
- builds the module snapshot in memory;
|
||||||
|
- builds `briefing.Metadata` and the v4 prompt package in memory;
|
||||||
|
- marshals YAML in memory;
|
||||||
|
- executes Promptkit with the existing preparation callback;
|
||||||
|
- writes requested preparation and execution debug captures only;
|
||||||
|
- requires a completed passed Promptkit validation;
|
||||||
|
- validates and decodes generated text;
|
||||||
|
- builds the render context and renders Markdown in memory;
|
||||||
|
- atomically writes the selected output; and
|
||||||
|
- notifies only after publication when notification is enabled.
|
||||||
|
2. Delete all ordinary calls that save module snapshots, data packages,
|
||||||
|
prompt preparation/execution, raw output, validated output, render context,
|
||||||
|
metadata, or managed reports.
|
||||||
|
3. Remove `DataPackagePath` from `promptexec.ExecuteRequest`,
|
||||||
|
`promptexec.Preparation`, `promptexec.Execution`, and debug artifact
|
||||||
|
mappings. Change the Promptkit adapter input from `InlineWithURI` using a
|
||||||
|
filesystem path to `promptkit.Inline`; the input remains copied inline and
|
||||||
|
its hashes remain available. Advance the changed debug schema identifiers
|
||||||
|
from `weatherreporter.prompt_preparation_debug.v1` and
|
||||||
|
`weatherreporter.prompt_execution_debug.v1` to their corresponding `v2`
|
||||||
|
identifiers without adding compatibility readers.
|
||||||
|
4. Preserve failure classification and context. A debug-write error remains an
|
||||||
|
invalid-configuration failure and the preparation callback must still stop
|
||||||
|
the provider when it fails. Operational provider failure and completed
|
||||||
|
validation rejection remain distinct.
|
||||||
|
5. Redesign `ReportResult` as an active result rather than an artifact index.
|
||||||
|
Retain only:
|
||||||
|
- report ID/name, prompt ID/version, RunID, generation time, timezone, and
|
||||||
|
valid period;
|
||||||
|
- selected profile ID, backend ID, and model name once inspected;
|
||||||
|
- source warnings;
|
||||||
|
- validation status when execution reached validation;
|
||||||
|
- final `OutputPath` once publication succeeds;
|
||||||
|
- `LLMDebugPath` when explicitly created; and
|
||||||
|
- notification result.
|
||||||
|
Do not retain module snapshots, prompt packages, generated bodies, render
|
||||||
|
contexts, state metadata, or transient paths in the result.
|
||||||
|
6. Make the CLI generate summary map directly from this active result and
|
||||||
|
remove `ReportPath`, `MetadataPath`, `DataPackagePath`,
|
||||||
|
`PreparationPath`, `ExecutionPath`, `GeneratedTextRawPath`,
|
||||||
|
`GeneratedTextPath`, `RenderContextPath`, and `NotificationPath`.
|
||||||
|
7. Apply the same safe identity/profile/warning/output fields to
|
||||||
|
`BatchReportResult`. Keep batch failure accounting and sequential execution.
|
||||||
|
8. Remove `Store` from `GenerateRequest` and `BatchRequest`. Remove
|
||||||
|
`defaultStore` and all persistence-only finalization helpers in this stage.
|
||||||
|
9. Keep app tests behavioral. Replace receipt/checkpoint assertions with a
|
||||||
|
compact matrix covering success, each consequential failure boundary,
|
||||||
|
partial results, inspection-before-collection, output atomicity, effective
|
||||||
|
profile propagation, debug capture, and notification sequencing.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./internal/app
|
||||||
|
go test ./internal/cli ./internal/adapters/promptkit
|
||||||
|
go test ./...
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
Single and batch generation share a state-free pipeline, ordinary success
|
||||||
|
leaves only selected outputs, and no app production path imports
|
||||||
|
`internal/state`.
|
||||||
|
|
||||||
|
## Stage 8: Remove Historical Inspection And Prior Compatibility
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Delete public and internal surfaces whose only purpose is reading prior runs.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Delete `internal/app/inspect.go` and all inspection request/result types and
|
||||||
|
focused tests.
|
||||||
|
2. Remove the top-level `inspect` dispatch, parsers, `--limit` handling,
|
||||||
|
command tables, help text, and CLI tests for:
|
||||||
|
`reports`, `metadata`, `modules`, `data-package`, `prior`, and `sources`.
|
||||||
|
`inspect` becomes an unknown command; do not retain a tombstone command.
|
||||||
|
3. Remove report `ComparisonStrategy`, comparison constants,
|
||||||
|
`CompatiblePriorIDs`, compatibility helpers, and registry tests.
|
||||||
|
4. Remove `FindPriorSnapshot`, `PriorSnapshot`, prior compatibility helpers,
|
||||||
|
and their tests from the still-transitional state package so it continues
|
||||||
|
to compile until full deletion.
|
||||||
|
5. Remove state load/list methods that existed only for CLI inspection where
|
||||||
|
doing so is clean and local. Do not spend effort preserving a smaller
|
||||||
|
historical reader that Stage 9 will delete.
|
||||||
|
6. Ensure `generate` and `run` parsing, help, summaries, and error behavior
|
||||||
|
remain intact.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./internal/report ./internal/app ./internal/cli ./internal/state
|
||||||
|
go test ./...
|
||||||
|
go run ./cmd/weatherreporter --help
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
Assert that `inspect` is rejected as an unknown command and no inspection
|
||||||
|
subcommand appears in help.
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
No public or app-level historical inspection contract remains, and report
|
||||||
|
definitions contain no prior-run compatibility policy.
|
||||||
|
|
||||||
|
## Stage 9: Delete The Workspace And State Subsystem
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Remove the now-unreferenced durable-state implementation and configuration.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Delete the remaining `internal/state` package and all of its tests. Do not
|
||||||
|
preserve metadata structs, artifact schemas, validators, path builders,
|
||||||
|
filesystem stores, or compatibility readers in another package.
|
||||||
|
2. Remove `WorkspaceConfig`, `Config.Workspace`, workspace defaults,
|
||||||
|
validation, YAML fixtures, and test helpers.
|
||||||
|
3. Add strict-loading coverage showing that a top-level `workspace:` stanza is
|
||||||
|
rejected as unknown. Existing legacy configuration is intentionally not
|
||||||
|
accepted.
|
||||||
|
4. Remove workspace and Recent Changes sections from maintained examples.
|
||||||
|
Keep every example complete, secret-free, and accepted by the production
|
||||||
|
loader.
|
||||||
|
5. Remove dead app code exposed by the deletion, including `FetchBundle`,
|
||||||
|
`FetchAndSaveBundle`, store helpers, artifact conversion helpers, copy
|
||||||
|
helpers, imports, and persistence-only test infrastructure. Neither fetch
|
||||||
|
helper currently has a production caller.
|
||||||
|
6. Keep state-independent atomic output helpers in `internal/fileutil`, update
|
||||||
|
their package comments to describe operator-owned outputs, and delete the
|
||||||
|
now-unused `CopyFileAtomic` helper.
|
||||||
|
7. Verify production Go code contains no import of `internal/state` and no
|
||||||
|
construction of a directory named `workspace`.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./internal/config ./internal/fileutil ./internal/app ./internal/cli
|
||||||
|
go test ./...
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
`internal/state` and `workspace` configuration no longer exist, legacy fields
|
||||||
|
fail strict loading, and normal execution has no application-owned durable
|
||||||
|
state mechanism.
|
||||||
|
|
||||||
|
## Stage 10: Consolidate Stateless Behavioral Coverage
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Review the rewritten suite as a whole and retain a lean set of tests that
|
||||||
|
protect the new risks without preserving deleted implementation choreography.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Audit app and CLI tests that were rewritten in earlier stages. Consolidate
|
||||||
|
overlapping cases and delete helpers whose only value was constructing
|
||||||
|
stores, metadata, artifact paths, or prior snapshots.
|
||||||
|
2. Ensure durable offline coverage at the narrowest stable boundary for:
|
||||||
|
- default and explicit absolute output selection;
|
||||||
|
- relative override resolution from an injected working directory;
|
||||||
|
- Daily valid-date filenames and distinct multi-day batch outputs;
|
||||||
|
- preservation of an existing destination on generation, rendering,
|
||||||
|
output-write, or cancellation before publication;
|
||||||
|
- retention of the newly published output when notification fails;
|
||||||
|
- no output on pre-publication failure;
|
||||||
|
- successful items surviving partial batch failure;
|
||||||
|
- batch notification only after all outputs exist;
|
||||||
|
- Distributor source and bundle paths;
|
||||||
|
- inspection/profile validation before weather collection;
|
||||||
|
- safe effective profile/backend/model and source warnings in summaries;
|
||||||
|
- absence of historical/transient paths in JSON summaries;
|
||||||
|
- no ordinary debug directory creation;
|
||||||
|
- secure explicit debug capture and credential redaction; and
|
||||||
|
- no default workspace or intermediate artifacts after repeated successes
|
||||||
|
and failures.
|
||||||
|
3. Use real temporary directories and real internal rendering/file helpers.
|
||||||
|
Fake only Weather API collection, Promptkit/provider execution, clocks, and
|
||||||
|
Distributor delivery.
|
||||||
|
4. Avoid tests of private phase ordering unless the ordering is a stated
|
||||||
|
external requirement. Do not replace deleted state tests with broad
|
||||||
|
filesystem snapshots.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./internal/app ./internal/cli
|
||||||
|
go test ./internal/fileutil ./internal/promptdebug
|
||||||
|
go test ./...
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
The suite protects stateless product behavior and consequential failure
|
||||||
|
boundaries without retaining obsolete state-oriented fixtures or redundant
|
||||||
|
mock choreography.
|
||||||
|
|
||||||
|
## Stage 11: Publish User, Operator, And Policy Documentation
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Publish the user-visible, operational, and normative stateless contracts in
|
||||||
|
their canonical owners.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Update `README.md` so the shortest useful command relies on the documented
|
||||||
|
current-directory output and links to canonical CLI and operations details.
|
||||||
|
2. Update `docs/cli.md` with:
|
||||||
|
- removal of `inspect`;
|
||||||
|
- default and explicit output behavior;
|
||||||
|
- absolute `outputPath` summaries;
|
||||||
|
- retained identity/profile/model/warning/debug/notification fields; and
|
||||||
|
- removal of historical artifact path fields.
|
||||||
|
3. Update `docs/config.md` and maintained examples to remove `workspace` and
|
||||||
|
`recent_change`. Keep Promptkit debug and notification configuration in
|
||||||
|
their existing canonical owners.
|
||||||
|
4. Rewrite `docs/operations.md` around operator-owned outputs, atomic
|
||||||
|
replacement, batch partial success, Distributor ordering, explicit debug
|
||||||
|
capture, and precise manual legacy-workspace cleanup. Remove all inspection,
|
||||||
|
metadata, receipt, recovery, and managed-workspace procedures.
|
||||||
|
5. Update `docs/policy/architecture.md` to make stateless execution,
|
||||||
|
in-memory processing, operator-owned atomic outputs, and state-free
|
||||||
|
notification normative. Remove `internal/state` and prior-comparison
|
||||||
|
ownership and persistence invariants.
|
||||||
|
6. Update `docs/policy/documentation.md` so Operations owns output lifecycle,
|
||||||
|
diagnosis, legacy cleanup, and explicit debug handling rather than physical
|
||||||
|
workspace and inspection contracts.
|
||||||
|
7. Update `docs/policy/testing.md` where its examples assign behavior to state
|
||||||
|
tests or name persistence/inspection as current app workflow contracts.
|
||||||
|
Preserve its general risk-based guidance.
|
||||||
|
8. Update `docs/development.md` package inventory and task guide for the
|
||||||
|
stateless package layout, removed inspection workflow, and operator-output
|
||||||
|
boundary. Route detailed subsystem work to its canonical internal or
|
||||||
|
integration document rather than duplicating it.
|
||||||
|
9. Leave `docs/releases/v0.9.0.md` unchanged as a historical record. Do not
|
||||||
|
create a new release note without a selected version. Confirm that the
|
||||||
|
future note must call out removed commands and fields, default outputs,
|
||||||
|
prompt contract changes, and manual legacy cleanup.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./...
|
||||||
|
go run ./cmd/weatherreporter --help
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
Check every changed repository-relative link, maintained YAML example, command,
|
||||||
|
flag, field, and output filename against executable sources.
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
User, operator, policy, development, and example documentation describe the
|
||||||
|
implemented stateless contract, and historical release notes remain unchanged.
|
||||||
|
|
||||||
|
## Stage 12: Reconcile Internal And Integration Documentation
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Bring maintainer-facing subsystem and external-contract documentation into
|
||||||
|
line with the implemented package boundaries without duplicating user-facing
|
||||||
|
contracts.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Delete `docs/internal/state.md` and `docs/internal/changes.md` and repair all
|
||||||
|
incoming links.
|
||||||
|
2. Update app orchestration internals for the in-memory workflow, partial
|
||||||
|
active results, atomic output, notification order, and batch isolation.
|
||||||
|
3. Update CLI internals for working-directory capture, destination resolution,
|
||||||
|
stateless summaries, and removal of inspection dispatch.
|
||||||
|
4. Update prompt-input internals for v4 without `recent_changes`, report
|
||||||
|
registry internals for output naming without comparison policy, and module
|
||||||
|
and generated-text internals only where their actual contracts changed.
|
||||||
|
5. Update Promptkit adapter internals and
|
||||||
|
`docs/integrations/promptkit.md` for inline input without a filesystem URI,
|
||||||
|
exact prompt version `2.0.0`, active safe provenance, and explicit debug
|
||||||
|
capture.
|
||||||
|
6. Update Distributor adapter and integration documents so source files are
|
||||||
|
operator outputs and notification state is not retained. Preserve the
|
||||||
|
remote API and bundle-path contract.
|
||||||
|
7. Review weather-data, collection, template, and other internal/integration
|
||||||
|
documents for stale references, but edit only documents whose owned
|
||||||
|
contracts changed.
|
||||||
|
8. Do not mark either roadmap implemented in this stage; Stage 13 owns that
|
||||||
|
status transition after the repository-wide gate. Do not turn either
|
||||||
|
roadmap into a second current-state reference.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./...
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
Validate every changed repository-relative link and verify each named package,
|
||||||
|
schema, prompt version, field, and integration path against executable sources.
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
No current internal or integration document describes local comparison,
|
||||||
|
historical state, inspection, managed-report sources, or durable prompt
|
||||||
|
provenance, and roadmap status accurately reflects completion.
|
||||||
|
|
||||||
|
## Stage 13: Run The Repository Exit Gate
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Verify the complete refactor as one coherent change and remove any remaining
|
||||||
|
legacy coupling before declaring implementation complete.
|
||||||
|
|
||||||
|
### Work
|
||||||
|
|
||||||
|
1. Run `gofmt` on every changed Go file and review the complete diff for stale
|
||||||
|
compatibility code, unnecessary abstractions, accidental content capture,
|
||||||
|
or user-owned unrelated changes.
|
||||||
|
2. Search production code, tests, examples, and current-state documentation
|
||||||
|
for obsolete `internal/state` imports, `workspace` and `recent_change`
|
||||||
|
configuration, `recent_changes` prompt input, comparison strategy fields,
|
||||||
|
inspection commands, managed-report terminology, and removed artifact-path
|
||||||
|
summary fields. Historical `v0.9.0` release notes and roadmap discussion of
|
||||||
|
removed behavior are allowed.
|
||||||
|
3. Verify the built help contains only `generate` and `run` action families
|
||||||
|
plus top-level help/version behavior.
|
||||||
|
4. Verify from focused offline CLI tests that commands run in a clean temporary
|
||||||
|
working directory and leave only expected Markdown outputs unless a debug
|
||||||
|
directory was explicitly supplied.
|
||||||
|
5. Confirm no test, example, or default path depends on the developer machine,
|
||||||
|
live credentials, or external services.
|
||||||
|
6. Mark the roadmap and plan complete only after all gates pass. Do not create
|
||||||
|
or tag a release in this implementation plan.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git diff --name-only --diff-filter=ACM -- '*.go' | xargs -r gofmt -w
|
||||||
|
go test ./...
|
||||||
|
go test -race ./...
|
||||||
|
go vet ./...
|
||||||
|
go build ./...
|
||||||
|
go run ./cmd/weatherreporter --help
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exit Gate
|
||||||
|
|
||||||
|
Weatherreporter builds and passes its deterministic offline suite; ordinary
|
||||||
|
actions are stateless and leave only selected outputs; debug and Distributor
|
||||||
|
boundaries remain safe; documentation matches implementation; and no required
|
||||||
|
work remains.
|
||||||
|
|
||||||
|
## Open Questions
|
||||||
|
|
||||||
|
None. The roadmap supplies all product and policy decisions required to
|
||||||
|
implement these stages.
|
||||||
Reference in New Issue
Block a user