 # Diagnostic Help Messages Implementation Plan

 > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

 **Goal:** Ensure that all non-allowed diagnostics (errors, warnings, infos/suggestions) carry a concrete “Help” message guiding users how to fix or improve their code, both in CLI/ariadne output and in the REPL.

 **Architecture:** Centralise default help text per `DiagCode` in `diag.rs`, and make `Diag::new` automatically fill in help when a call-site does not provide one, while still allowing call-sites to override with richer, context-specific help. Keep phase-specific helper constructors (`parse::error`, `ir::error`, `opt::error`, `compose`) as the only places that know about AST/IR details and spans. REPL output will reuse the same help field, formatting it as an optional trailing “help: …” line for each diagnostic.

 **Tech Stack:** Rust (core crate, `ariadne` for diagnostics), existing test suite (`cargo test`, especially `tests/parse_dsl.rs`, `tests/repl_*`, and unit tests in `parse::error`, `ir::error`, `opt::const_fold`).

 ---

 ### Task 1: Add default help API on `DiagCode`

 **Files:**
 - Modify: `src/diag.rs`

 **Steps:**
 1. Add a `pub fn default_help(self) -> Option<&'static str>` method on `DiagCode` that returns a stable, human-oriented help text for codes that do not already have rich, dynamic help at construction sites.
 2. Provide default help for at least:
    - `ParseIntImaginary`
    - `ParseUnknownDType`
    - `ParseUndefinedVar`
    - `ParseReservedIdentifier`
    - `ParseSyntax` (generic hint to check surrounding tokens / parentheses)
    - All `Lower*` hard errors
    - `LowerImplicitPromotion`, `LowerFloatPrecisionLoss`, `LowerUnsafeUIntToSInt`, `LowerRedundantCastChain`
    - `OptPromotion`, `ConstFoldUnsafe`
    - `ComposeSymbolReuse`
 3. Keep default help generic and stable (no dynamic lists or spans), leaving call-sites free to provide more specific hints when needed.

 ### Task 2: Wire default help into `Diag::new`

 **Files:**
 - Modify: `src/diag.rs`

 **Steps:**
 1. Update `Diag::new` so that when the `hint` argument is `None`, it falls back to `code.default_help().map(|s| s.to_string())`.
 2. Keep existing call-sites that pass an explicit `Some(hint)` unchanged; those should override the default help.
 3. Add a small unit test in `diag.rs` that constructs a `Diag` with `hint: None` for a code that has `default_help()` and asserts that `diag.hint.is_some()` and that `report_string_default` includes the help text.

 ### Task 3: Review and adjust phase-specific diagnostic constructors

 **Files:**
 - Modify: `src/parse/error.rs`
 - Modify: `src/ir/error.rs`
 - Modify: `src/opt/error.rs`
 - Modify: `src/opt/const_fold.rs`
 - Modify: `src/compose.rs`

 **Steps:**
 1. For constructors that already pass a `Some(hint)` (e.g. `parse_unknown_dtype`, `parse_reserved_identifier`, `lower_implicit_promotion`, `lower_float_precision_loss`, `lower_unsafe_uint_to_sint`, `lower_redundant_cast_chain`, `compose_with_diags`’s `ComposeSymbolReuse`), leave them intact; they provide richer, context-aware help.
 2. For constructors currently passing `None` as the hint, rely on `DiagCode::default_help` instead of inlining new hints at each call-site, unless phase-specific context makes a clearly better suggestion.
 3. Ensure any direct `Diag::new` usages in optimisation or compose code that represent user-facing diagnostics are covered by either a default help or an explicit, contextual help string.

 ### Task 4: Extend REPL diagnostic formatting to surface help

 **Files:**
 - Modify: `src/repl.rs`

 **Steps:**
 1. Update the manual `Diag::new` call for REPL input dtype errors (`ParseUnknownDType` in `process_line`) to rely on default help (no need to pass a custom hint).
 2. Extend `format_diag_line` so that, when `diag.hint` is present, it appends a second line such as `  help: <hint>` after the main diagnostic line.
 3. Add or update tests in `tests/repl_*` (or add a focused unit test for `format_diag_line`) to assert that when a `Diag` with a help message is printed, the help line appears.

 ### Task 5: Update diagnostics documentation

 **Files:**
 - Modify: `docs/diagnostics.md`

 **Steps:**
 1. Add a short subsection describing that each `DiagCode` may define a default help text, and that call-sites can override with richer help.
 2. Mention that REPL and CLI outputs both surface these help messages (via ariadne’s `with_help` and the REPL formatter).
 3. Optionally add one or two concrete examples showing an error/warning/suggestion with its help message and how a user might act on it.

 ### Task 6: Run tests and iterate

 **Files:**
 - Test: `cargo test`

 **Steps:**
 1. Run the full test suite with `cargo test`.
 2. Fix any compilation errors or failing tests by updating expectations (e.g. where output formatting changed) or adjusting help texts.
 3. Re-run `cargo test` until all tests pass.
 4. Optionally add a small end-to-end test (e.g. in `tests/repl_session.rs` or `tests/e2e_parse_lower_interp.rs`) that asserts at least one diagnostic printed by the REPL or e2e pipeline includes a `help:` line.
