docs(hint): defer pre-submit-diagnostic route + diagnostic.* blocks (ADR-0053)
Phase C scope decision: Diagnostic carries no class key, so the F1 diagnostic route would need a class field threaded through every diagnostic site (broad change) for marginal value — tier-2 already surfaces diagnostics and many duplicate the runtime error classes. Defer the route + the ~33 diagnostic.* tier-3 blocks to issue #38. v1 ships command-form hints + 9 runtime error-class hints (comprehensive for those). Updates ADR-0053 D2/D6/Status/OOS + README.
This commit is contained in:
@@ -10,10 +10,13 @@ Phase B implementation (2026-06-15): the first exemplar showed per-*node*
|
||||
keying is too coarse for multi-form commands (`add`/`drop`/`show`/
|
||||
`create`), so D3 now keys tier-3 content **per form** via a
|
||||
`hint_ids: &[&str]` array mirroring `usage_ids` — and **clause-concept
|
||||
hints** are recorded as a deferred extension (separate tracking issue).
|
||||
The parallel question of whether the in-app `help` command should
|
||||
likewise distinguish advanced-SQL forms is tracked **separately** as
|
||||
Gitea issue #36 (it touches shipped, ADR-backed `help` behaviour).
|
||||
hints** are recorded as a deferred extension (issue #37). During Phase C
|
||||
the **pre-submit-diagnostic route + the ~33 `diagnostic.*` blocks** were
|
||||
**deferred** (issue #38) — `Diagnostic` doesn't carry its class key, so
|
||||
the route needs a broad change for marginal value (D6). v1 therefore
|
||||
ships command-form hints + the 9 runtime error-class hints. The parallel
|
||||
question of whether the in-app `help` command should likewise distinguish
|
||||
advanced-SQL forms is tracked **separately** as Gitea issue #36.
|
||||
|
||||
Decided in conversation 2026-06-14. Closes the last open piece of **A1**
|
||||
(the canonical app-command set, ADR-0003): every app command is
|
||||
@@ -112,19 +115,13 @@ F1 is inert behind a modal and while a sidebar panel holds navigation
|
||||
focus (consistent with the existing `handle_key` gates, ADR-0046); it is
|
||||
active in the input context in both Simple and Advanced mode.
|
||||
|
||||
**Two error sources, one namespace.** Errors come in two kinds and reach
|
||||
`hint` by different routes:
|
||||
|
||||
- **Pre-submit diagnostics** (the ~33 `diagnostic.*` classes — arity,
|
||||
type, unknown table/column) are computed *while typing* by the walker.
|
||||
The **F1 live-input path** reads the current under-cursor diagnostic
|
||||
directly from the walker (the same source the ambient panel uses) and
|
||||
renders its `hint.err.<class>` block — no stored state needed.
|
||||
- **Runtime errors** (the 9 `translate_error` classes) occur *after*
|
||||
submit. The **`hint` command / empty-input F1** path reads them via the
|
||||
stored `last_error_hint_key` (D5).
|
||||
|
||||
Both render from the same `hint.err.*` namespace. **`:`-prefix handling:**
|
||||
**Error routes.** **Runtime errors** (the 9 `translate_error` classes)
|
||||
occur *after* submit; the **`hint` command / empty-input F1** path reads
|
||||
them via the stored `last_error_hint_key` (D5) and renders their
|
||||
`hint.err.<class>` block. (A second route for **pre-submit diagnostics**
|
||||
on the F1 live-input path was specified but is **deferred** — D6 / issue
|
||||
#38; with a diagnostic present, F1 shows the command block and tier-2
|
||||
shows the diagnostic.) **`:`-prefix handling:**
|
||||
on the simple-mode one-shot escape (`: SELECT …`), command
|
||||
identification for the F1 path strips the leading `:` first, so the
|
||||
advanced form is matched.
|
||||
@@ -220,26 +217,37 @@ Option<String>`** — set at the `translate_error` call sites
|
||||
cleared when a later command succeeds. Absent → the "getting started"
|
||||
pointer.
|
||||
|
||||
The **pre-submit-diagnostic route** (the F1 live-input path) needs no
|
||||
stored state: it reads the current diagnostic from the walker at F1 time
|
||||
(D2). This is the cleaner split the `/runda` pass surfaced — typing-time
|
||||
diagnostics and post-submit runtime errors are genuinely different
|
||||
sources and should not be funnelled through one stored key.
|
||||
The **pre-submit-diagnostic route** (the F1 live-input path reading the
|
||||
under-cursor diagnostic) is **deferred** — see the scope note in D6.
|
||||
|
||||
### D6 — Content scope: comprehensive for v1
|
||||
### D6 — Content scope for v1
|
||||
|
||||
v1 ships tier-3 content for the **whole inventory**, not a subset (the
|
||||
graceful tier-2 fallback below is a safety net, not the plan):
|
||||
v1 ships tier-3 content for the **command forms and runtime error
|
||||
classes** — comprehensive for those (the graceful tier-2 fallback below
|
||||
is a safety net, not the plan):
|
||||
|
||||
- **~37 command forms** — every distinct node in `REGISTRY` gets its own
|
||||
`hint.cmd.<hint_id>` block (app + DSL + DDL + advanced-mode SQL forms),
|
||||
each with a **mode-correct example** (the advanced-SQL forms show SQL
|
||||
syntax, their simple siblings show DSL — no sharing).
|
||||
- **9 runtime error classes** — `unique`, `foreign_key` (×4 sides),
|
||||
`not_null`, `check`, `type_mismatch`, `not_found`, `already_exists`,
|
||||
`generic`, `invalid_value` — each gets a `hint.err.*` block.
|
||||
- **~33 `diagnostic.*` pre-submit classes** — arity, type, unknown
|
||||
table/column, etc. — each gets a `hint.err.*` block.
|
||||
- **9 runtime error classes** — `unique`, `foreign_key` (child/parent
|
||||
side), `not_null`, `check`, `type_mismatch`, `not_found`,
|
||||
`already_exists`, `generic`, `invalid_value` — each gets a
|
||||
`hint.err.*` block.
|
||||
|
||||
**Deferred — the ~33 `diagnostic.*` pre-submit classes and the F1
|
||||
diagnostic route** *(Phase C scope decision, 2026-06-15; issue #38)*. The
|
||||
original "comprehensive" scope included them, but implementation revealed
|
||||
`Diagnostic` (`walker/outcome.rs`) carries only its rendered `message`,
|
||||
not its class key — so a live diagnostic can't be mapped to
|
||||
`hint.err.<class>` without adding a `class` field threaded through every
|
||||
diagnostic-creation site (a broad change). Weighed against the value, it
|
||||
isn't worth it for v1: pre-submit diagnostics are already surfaced by
|
||||
tier-2 (ambient message + validity indicator, ADR-0027); F1 still shows
|
||||
the useful command block when a diagnostic is present; and many
|
||||
diagnostic classes duplicate runtime classes already covered
|
||||
(`type_mismatch`, `unknown_table`↔`not_found`, arity↔`invalid_value`).
|
||||
Deferred to issue #38, additively (the keying doesn't lock it out).
|
||||
|
||||
The full enumerated checklist is the implementation plan's tracking
|
||||
artifact (see *Content inventory*, below).
|
||||
@@ -339,26 +347,26 @@ Hint — add relationship
|
||||
`App` state (`last_error_hint_key`), and one new renderer family
|
||||
(`note_hint*`); the `AppCommand` enum gains `Hint`, the grammar a `HINT`
|
||||
node, the REGISTRY one entry.
|
||||
- **A large, durable content corpus** (~37 command blocks + ~42 error/
|
||||
diagnostic blocks ≈ 80) enters the catalogue under `hint.cmd.*` /
|
||||
- **A durable content corpus** (~37 command blocks + 10 runtime
|
||||
error-class blocks) enters the catalogue under `hint.cmd.*` /
|
||||
`hint.err.*`, validated by `keys.rs`. This is ongoing surface area: new
|
||||
commands/error classes should ship with their tier-3 hint (a checklist
|
||||
item for future feature ADRs).
|
||||
item for future feature ADRs). (Diagnostic-class blocks deferred — #38.)
|
||||
- **Testing:** Tier-1 unit tests for the trigger matrix (F1 with
|
||||
empty/non-empty input; `hint` with/without a recent error;
|
||||
`last_error_hint_key` set on the `translate_error` sites and cleared on
|
||||
success; the pre-submit-diagnostic vs runtime-error routing; the `:`
|
||||
strip), the command-identification logic, and the tier-2 fallback;
|
||||
Tier-2 `insta` snapshots for a representative rendered hint block;
|
||||
Tier-3 integration tests for the end-to-end flows (type a partial
|
||||
command → F1 → block appears, **buffer and completion memo untouched**;
|
||||
run a failing command → `hint` → error expansion). **A
|
||||
comprehensiveness coverage test** (enforces D6): iterate the REGISTRY
|
||||
and assert every node has a `hint_id` resolving to a `hint.cmd.*` block,
|
||||
and every runtime-error/diagnostic class has a `hint.err.*` block —
|
||||
`keys.rs` only checks that *referenced* keys resolve, not that every
|
||||
command/error *has* one, so this test is what makes "comprehensive"
|
||||
enforceable rather than aspirational.
|
||||
success; the mode-aware form resolution; the `:` strip), the
|
||||
command-identification logic, and the tier-2 fallback; Tier-2 `insta`
|
||||
snapshots for a representative rendered hint block; Tier-3 integration
|
||||
tests for the end-to-end flows (type a partial command → F1 → block
|
||||
appears, **buffer and completion memo untouched**; run a failing
|
||||
command → `hint` → error expansion). **A comprehensiveness coverage
|
||||
test** (enforces D6): iterate the REGISTRY and assert every node with a
|
||||
`hint_ids` entry resolves to a `hint.cmd.*` block, and every runtime
|
||||
error class resolves to a `hint.err.*` block — `keys.rs` only checks
|
||||
that *referenced* keys resolve, not that every command/error *has* one,
|
||||
so this test is what makes the scope enforceable rather than
|
||||
aspirational. (Diagnostic classes are out of this scope — D6 / #38.)
|
||||
|
||||
## Out of scope
|
||||
|
||||
@@ -381,6 +389,11 @@ Hint — add relationship
|
||||
recognized clause, deeper than tier-2's candidate list but narrower than
|
||||
the per-form block. Per-form keying (D3) does not lock it out. To be
|
||||
tackled as a deliberate follow-up job, not gated on usage statistics.
|
||||
- **Pre-submit-diagnostic route + `diagnostic.*` tier-3 blocks** — OOS
|
||||
(deferred, issue #38): needs a class field on `Diagnostic` threaded
|
||||
through every creation site (broad change) for marginal value, since
|
||||
tier-2 already surfaces diagnostics and many duplicate runtime classes
|
||||
(D6).
|
||||
|
||||
## Content inventory (implementation tracking)
|
||||
|
||||
@@ -401,4 +414,5 @@ The implementation plan enumerates and checks off every block:
|
||||
- **`hint.err.*`** — one per runtime error class (`unique`,
|
||||
`foreign_key.{child,parent}_side`, `not_null`, `check`,
|
||||
`type_mismatch`, `not_found`, `already_exists`, `generic`,
|
||||
`invalid_value`) and per `diagnostic.*` pre-submit class.
|
||||
`invalid_value`). The `diagnostic.*` pre-submit classes are **deferred**
|
||||
(D6 / issue #38).
|
||||
|
||||
Reference in New Issue
Block a user