fbf449f9e0
Settle the cast toolchain (STYLE.md #9) and build the demo pipeline end to end. Driver: autocast, chosen by spike — its !Interactive feeds keys to the running TUI and captures the redraw, the right model for a full-screen crossterm app. asciinema-automation was rejected (assumes shell echo/\n Enter; produced a garbled cast against the TUI). - add asciinema-player; Cast.astro (player island) + Demo.astro (the WASM-swap seam, ADR-website-001 §3) - casts-src/: human-readable command-lists (casts.mjs) + generate.mjs, exposed as `pnpm casts`; expands steps to autocast YAML and records to public/casts/. Command-lists are the durable source; .cast files are regenerable (final re-record sweep due once the app is locked). - quickstart.cast (create -> add columns -> insert -> show data) embedded on the landing page above the feature cards. Verified: pnpm build clean (25 pages); player + cast bundled and served; landing HTML references the cast. Visual playback check pending (no headless browser here — verify via dev server over the tunnel).
200 lines
10 KiB
Markdown
200 lines
10 KiB
Markdown
# Documentation style guide (living)
|
||
|
||
This is the **living** home for documentation authoring conventions for the
|
||
RDBMS Playground website. It grows as we write.
|
||
|
||
- **Binding rules** come from
|
||
[ADR-website-001 §7](../docs/website/adr/20260604-adr-website-001.md);
|
||
this guide must not contradict them. If a convention is significant,
|
||
durable, or contested, it is decided in an **ADR** (new or amended), and
|
||
this guide references it. Finer, settled conventions live here directly.
|
||
- **Open decisions** (not yet settled) are tracked at the bottom so we
|
||
decide them deliberately rather than re-deciding per page. When one
|
||
settles, move it up into the body (and to an ADR if it's significant).
|
||
|
||
Status tags used below: **[DECIDED]** (binding or settled) ·
|
||
**[OPEN]** (to be decided — see the log).
|
||
|
||
---
|
||
|
||
## Terminology & wording [DECIDED — ADR-website-001 §7]
|
||
|
||
- **No "DSL".** It is internal jargon. Use **simple mode** (the playground's
|
||
keyword command language) and **advanced mode** (SQL).
|
||
- **No engine name.** Never name SQLite / STRICT / rusqlite / PRAGMA in
|
||
user-facing copy. Say **"the database"** or **"the engine"**. (Continues
|
||
the user-facing posture of ADR-0002.)
|
||
- Preferred terms (extend as we go): "command", "project", "table",
|
||
"column", "relationship" (the user-facing word for a declared foreign-key
|
||
link), "constraint", "index".
|
||
- Add new banned/preferred terms here as they come up, with a one-line
|
||
reason.
|
||
|
||
## Voice & tone [DECIDED, refine as needed]
|
||
|
||
- **Teaching-first.** Pedagogy wins ties (CLAUDE.md). Explain the *why*, not
|
||
just the *how*; the audience spans beginners through learners ready for
|
||
raw SQL.
|
||
- Second person ("you"), present tense. Imperative mood for step
|
||
instructions ("Create a table…").
|
||
- Prefer short sentences and concrete examples over abstract prose.
|
||
|
||
## Structure [DECIDED]
|
||
|
||
Pragmatic, Diátaxis-influenced split (five top-level sidebar sections,
|
||
autogenerated per directory under `src/content/docs/`):
|
||
|
||
- **Getting started** — install, first project, simple vs. advanced, the
|
||
example database.
|
||
- **Using the playground** — *the application you drive*, kept distinct from
|
||
the database-language Reference: command-line options, the assistive editor
|
||
(completion / highlighting / `[ERR]`/`[WRN]` indicator / hints / in-line
|
||
editing), the output pane (scrolling), projects (save/load/new/rebuild),
|
||
undo & history, export & import, clipboard, getting help. (ADR-0003's
|
||
"app-level commands" + ADR-0022/0027 typing assistance + the CLI.)
|
||
- **Guides** — task-oriented how-tos. *These are the most important didactic
|
||
content and will be iterated for teaching quality before publication.*
|
||
- **Reference** — the exhaustive command/SQL/type surface. **Page
|
||
granularity: one page per topic / command-family** (Tables, Columns,
|
||
Relationships, Indexes, Constraints, Inserting & editing data, Querying,
|
||
Types, …), each covering the simple-mode and advanced-mode forms where
|
||
both apply. Hand-written now (the command surface is settled bar H1a
|
||
output); small post-release adjustments are expected and fine.
|
||
- **Concepts** — the "why": projects & storage, undo & history, etc.
|
||
|
||
Ground every reference page in source — `parse.usage.*` and `help.*` in
|
||
`src/friendly/strings/en-US.yaml`, `src/dsl/command.rs`, `src/dsl/types.rs`
|
||
— never paraphrase grammar from memory.
|
||
|
||
## "Planned / not yet available" callouts [DECIDED — ADR-website-001 §7]
|
||
|
||
Any capability that is not yet fully implemented is **omitted** or carries a
|
||
clear callout — never presented as shipped. Standard form: a Starlight aside
|
||
|
||
```md
|
||
:::caution[Planned]
|
||
This is planned and not yet available.
|
||
:::
|
||
```
|
||
|
||
## Examples & code [DECIDED]
|
||
|
||
- **Shared example database: a small library** — `authors`, `books`,
|
||
`members`, `loans` (see the canonical schema below). Reuse it across all
|
||
pages so readers build familiarity; it models 1:n (an author has many
|
||
books) and m:n (books ↔ members, through loans).
|
||
- Where both modes apply, show the **simple-mode** form and its
|
||
**advanced-mode (SQL)** equivalent — the in-app teaching echo already
|
||
pairs these, so docs mirror it.
|
||
- Prefer **worked examples** (a real command on the library schema) over
|
||
abstract prose, and **always cross-link** the related reference/guide
|
||
pages (use stubs so links resolve before a page is written).
|
||
- Code blocks for exact input/output; reserve casts for motion/flow.
|
||
|
||
### Code-block fences
|
||
|
||
- **Simple-mode commands → ` ```rdbms `** — custom highlight grammar in
|
||
`src/grammars/rdbms.mjs`, registered with Expressive Code in
|
||
`astro.config.mjs` (keywords + types coloured).
|
||
- **Advanced-mode SQL → ` ```sql `**; shell / install → ` ```sh `.
|
||
- A decorative `> ` prompt is prepended to `rdbms` lines via CSS
|
||
(`src/styles/global.css`) — **do not type `>` in the fence**. It is
|
||
copy-safe (Expressive Code's copy button uses `data-code`) and
|
||
`user-select:none`.
|
||
- **One command per line** in an `rdbms` block; a multi-line single
|
||
statement (e.g. advanced `CREATE TABLE`) belongs in a ` ```sql ` block,
|
||
where no prompt is added.
|
||
- **Command output → a plain unlabelled ` ``` ` fence** placed immediately
|
||
after the command block (no language, so no `> ` prompt and no
|
||
highlighting). Output must be **captured from the real app**, never
|
||
hand-drawn — box-drawing diagrams, query-plan trees, and data tables are
|
||
copied verbatim (trailing padding spaces trimmed). The capture method: a
|
||
throwaway in-crate test that builds the canonical library schema and prints
|
||
the rendered output (`render_structure_with_diagrams`,
|
||
`render_relationship_diagram`, `render_data_table`, `render_explain_plan`,
|
||
`show_list`), removed once the output is pasted. Colour is lost in a static
|
||
block (the structure still reads); the coloured/animated rendering is
|
||
earmarked for casts.
|
||
|
||
### Canonical library schema (source of truth for examples)
|
||
|
||
Use these exact names/types in every example:
|
||
|
||
| Table | Columns (playground types) |
|
||
|-----------|---------------------------------------------------------------------------------------------|
|
||
| `authors` | `author_id` serial (pk) · `name` text (not null) · `birth_year` int |
|
||
| `books` | `book_id` serial (pk) · `title` text (not null) · `author_id` int (→ authors) · `published` int · `isbn` text (unique) |
|
||
| `members` | `member_id` serial (pk) · `name` text (not null) · `joined` date |
|
||
| `loans` | `loan_id` serial (pk) · `book_id` int (→ books) · `member_id` int (→ members) · `loaned_on` date · `returned_on` date |
|
||
|
||
Relationships: `books.author_id → authors.author_id` (1:n); `loans` joins
|
||
`books` and `members` (the m:n bridge). Show `shortid` on the Types page via
|
||
a small standalone example, not by complicating this schema.
|
||
|
||
## asciinema casts [DECIDED]
|
||
|
||
- Casts show *flow/motion*; static code blocks show *exact input/output*.
|
||
Prefer a code block when a still example suffices.
|
||
- Pair a hero/landing cast with a text transcript or the equivalent docs
|
||
snippet (accessibility + SEO).
|
||
- **Driver: `autocast`** (ADR-website-001 §2; chosen by the 2026-06-10
|
||
spike). `autocast`'s `!Interactive` feeds keys to the running TUI and
|
||
captures the redraw — the correct model for a full-screen crossterm app.
|
||
`asciinema-automation` was rejected: it assumes *shell* semantics (Enter as
|
||
`\n`, and an `expect()` echo-check per keystroke), which a redrawing TUI
|
||
breaks — it produced a garbled cast.
|
||
- **Authoring workflow.** Source command-lists live in `casts-src/casts.mjs`
|
||
(human-readable steps: `type` / `wait` / `key`). `pnpm casts` runs
|
||
`casts-src/generate.mjs`, which expands them to autocast YAML (one key per
|
||
character; Enter = `^M`) and records to `public/casts/<name>.cast`. The
|
||
command-lists are the durable source; **`.cast` files are regenerable** —
|
||
re-run `pnpm casts` to re-record as the app evolves (a final sweep is due
|
||
once the app is locked). Needs a `cargo build` binary at `../target/debug`.
|
||
- **Embedding.** `Demo.astro` (the WASM-swap seam, ADR-website-001 §3) wraps
|
||
`Cast.astro` (asciinema-player island). Call sites use `Demo`.
|
||
- **Conventions.** Terminal geometry per cast (default 90×26); file name =
|
||
cast `name`; player theme `asciinema` for now. **[OPEN]**: light/dark player
|
||
theme sync with the Starlight theme toggle (player theme is currently fixed;
|
||
refine in Phase B).
|
||
|
||
## Formatting [DECIDED, refine]
|
||
|
||
- Starlight asides for notes/tips/cautions; tables for reference matrices
|
||
(types, constraints, referential actions).
|
||
- Keyboard keys rendered consistently (e.g. <kbd>Ctrl</kbd>+<kbd>Z</kbd>).
|
||
- Cross-link related pages; never expose ADR numbers or internal jargon to
|
||
the reader (ADRs are for us, not the docs audience).
|
||
|
||
---
|
||
|
||
## Open decisions log
|
||
|
||
Decide these as we write; record the outcome (and escalate to an ADR if
|
||
significant).
|
||
|
||
**Resolved (2026-06-10):**
|
||
9. ~~Cast scripting toolchain~~ → **`autocast`**, proven by spike over
|
||
`asciinema-automation` (which can't drive a full-screen TUI). Source
|
||
command-lists in `casts-src/`, `pnpm casts` to record. See the *asciinema
|
||
casts* section above. (Remaining sub-item: light/dark player theme sync —
|
||
folded into #8 / Phase B.)
|
||
|
||
**Resolved (2026-06-05):**
|
||
1. ~~Depth / organising spine~~ → **Pragmatic** four-section split (see
|
||
Structure above).
|
||
2. ~~Page granularity~~ → **one page per topic / command-family**, both
|
||
modes per page (see Structure).
|
||
3. ~~Standard example dataset~~ → **the library** (schema above).
|
||
4. ~~Simple-vs-advanced pairing~~ → **show both where both apply** (see
|
||
Examples).
|
||
5. ~~"Planned" callout~~ → standard `:::caution[Planned]` aside (see above).
|
||
6. ~~Reference generation vs hand-writing~~ → **hand-write now** (command
|
||
surface is settled bar H1a output; small later adjustments expected).
|
||
|
||
**Still open:**
|
||
7. **Versioning.** Version selectors at/after v1, or single-version for
|
||
launch? (Leaning single-version for launch.)
|
||
8. **SEO/meta conventions.** Title/description patterns, Open Graph — settle
|
||
with Phase B (landing) and the `site` URL. Also: light/dark player-theme
|
||
sync for embedded casts.
|