fix(hint): labelled tier-3 block format + snapshot (ADR-0053 /runda)

Final /runda found the rendered block was three bare unlabelled lines,
deviating from the approved exemplar format. Fix:
- emit_tier3_block now renders a `Hint` heading + aligned `What:` /
  `Example:` / `Concept:` lines (hint.block.* labels); concept stays muted
- lock the format with an insta snapshot (hint_block_insert)
- amend ADR-0053 D2/D4 + exemplars: drop the `Next:` line (tier-2 ambient
  already owns live position-awareness — user-confirmed), align exemplars
  to the shipped format

2499 pass / 1 ignored, clippy clean.
This commit is contained in:
claude@clouddev1
2026-06-15 16:45:47 +00:00
parent 447112b17f
commit 329adfc935
5 changed files with 82 additions and 29 deletions
@@ -113,7 +113,7 @@ into the output journal. (It must therefore be handled in `handle_key`
| Trigger | Buffer / state | Result |
|---|---|---|
| **F1** | non-empty input | tier-3 hint for the command being typed, plus the live "expected next" (from the walker's `tail_expected` / parser `expected`) |
| **F1** | non-empty input | tier-3 hint for the command being typed. (No "expected next" line — the always-on tier-2 ambient panel already shows it live; tier-2 owns position-awareness.) |
| **F1** | empty input, a recent error exists | tier-3 expansion of that error |
| **F1** | empty input, no recent error | a short "getting started" pointer (press F1 while typing a command; `help` for the full list) |
| **`hint`** (submitted) | a recent error exists | tier-3 expansion of that error (primary use) |
@@ -205,14 +205,17 @@ mechanics (e.g. `quit`); `what` + `example` are always present.
### D4 — Rendering
Both surfaces render through one new renderer, `App::note_hint*` (sibling
of `note_help`/`note_help_topic`, `src/app.rs`), emitting a small framed
block into the `output` buffer as `OutputKind::System` with
`OutputStyleClass::Hint` on the `what`/`concept` prose and `Neutral` on
the `example` line. The block is **persistent** (scrolls in the journal),
unlike the transient ambient panel — pressing F1 is an explicit request
to *keep* the deeper guidance on screen. The bottom keybinding strip
(ADR-0051) advertises F1 in the editing/typing state.
Both surfaces render through the `App::note_hint*` family (sibling of
`note_help`/`note_help_topic`, `src/app.rs`) via `emit_tier3_block`,
emitting into the `output` buffer as `OutputKind::System`: a **`Hint`
heading** followed by aligned **`What:` / `Example:` / `Concept:`** lines
(labels + heading from `hint.block.*`). The `concept` line is muted
(`OutputStyleClass::Hint`); the rest are plain. The block is
**persistent** (scrolls in the journal), unlike the transient ambient
panel — pressing F1 is an explicit request to *keep* the deeper guidance
on screen. Its rendered shape is locked by an `insta` snapshot
(`hint_block_insert`). The bottom keybinding strip (ADR-0051) advertises
F1 in the editing (leading) and default states.
### D5 — "Most recent (runtime) error" state
@@ -278,32 +281,31 @@ maintainer owns, content is produced in two stages:
**reviewable batches** (grouped by area: DDL, DML, app commands,
error classes), not one monolithic drop.
### Exemplars (the style reference to approve)
### Exemplars (the style reference; shipped as the rendered format)
**Command (F1 live-input), `insert`:**
**Command (F1 live-input), `insert`** (the rendered shape, locked by the
`hint_block_insert` snapshot — a `Hint` heading + aligned labels, no
`Next:` line since tier-2 owns position-awareness):
```
Hint — insert
Hint
What: Add one or more rows to a table.
Example: insert into Customers values ('Ann', 'ann@x.io')
Example: insert into Customers values ('Ann', 'ann@example.io')
Concept: A row is one record; each value lines up with a column, in
order. Columns typed serial/shortid fill themselves — leave
them out.
Next: a value list `(...)`, or `(col, ...) values (...)` to name columns
```
(The "Next:" line is the live expected-set from the walker, shown only on
the non-empty-input F1 path.)
**Error (`hint` command), foreign-key child-side violation:**
```
Hint — no parent row to point at
What: The value you inserted into Orders.customer_id doesn't match
any Customers row, so the foreign key has nothing to point at.
Example: First insert into Customers values ('Ann', ...)
Then insert into Orders values (..., 'Ann')
Hint
What: The value you gave for the child column doesn't match any
parent row, so the foreign key has nothing to point at.
Example: First insert the parent (insert into Customers …), then the
child that references it.
Concept: A foreign key is a promise that every child points at a real
parent. The parent must exist first. To allow orphans on
parent, so the parent must exist first. To allow orphans on
delete instead, set the relationship's `on delete` to
`set null` or `cascade`.
```
@@ -311,7 +313,7 @@ Hint — no parent row to point at
**Command (F1 live-input), `add 1:n relationship`:**
```
Hint — add relationship
Hint
What: Link two tables so a parent row can own many child rows.
Example: add 1:n relationship from Customers.id to Orders.customer_id
Concept: The "1:n" means one parent, many children. The child column