Commit Graph

402 Commits

Author SHA1 Message Date
claude@clouddev1 dfb5f0b1b1 docs: move website ADR + plan into a dedicated docs/website/ namespace
The website subproject drew ADR numbers from the same global integer pool
as main, so every merge risked a collision — this already happened twice
(drafted 0042, bumped to 0044, both landing on numbers main had taken; main
has now used 0044 for relationship visualization). Give the website its own
ADR namespace so the two never compete again.

- docs/adr/0044-public-website-...md
    -> docs/website/adr/20260604-adr-website-001.md  (id: ADR-website-001)
- docs/plans/20260604-adr-0044-website.md
    -> docs/website/plans/20260604-website-implementation-plan.md
- new docs/website/adr/README.md index (dated <date>-adr-website-<NNN> seq)
- docs/adr/README.md: drop the 0044 entry, add a namespace pointer in the
  intro (keeps the list tail == merge-base, so main's 0044 merges cleanly)
- ADR-0000: record the subproject-ADR-namespace convention
- update references in STYLE.md, astro.config.mjs, the plan body

Handoff files left untouched as point-in-time history.
2026-06-10 11:04:55 +00:00
claude@clouddev1 39e97ac3f9 docs: website-branch session handoff (website-1)
First handoff for the website work, on a branch-scoped name sequence
(…-website-handoff-N.md) to avoid colliding with main's handoff-NN files.
Captures stack/layout, the five-section structure, binding conventions
(no DSL / no engine name / fence + prompt + copy rules), the canonical
library schema, a verified-syntax cheat-sheet, the dev-server IPv4 gotcha,
next-work priorities (fill the 6 Reference stubs, iterate guides, Phase B
landing, deferred casts), and process pins.
2026-06-10 10:41:45 +00:00
claude@clouddev1 1152b0dc14 docs: session handoff 60 — Gitea migration cleanup + V1 relationship visualization (ADR-0044) 2026-06-10 10:40:48 +00:00
claude@clouddev1 936d9254c0 feat: add "Using the playground" section + Reference skeleton
Restructure the docs into five top-level sections, splitting the
application you drive from the database language you build with.

- New "Using the playground" section: 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/redo & history; export & import; clipboard; getting help. Grounded in
  the in-app help/usage and ADR-0003/0022/0027.
- Reference: seed the remaining topic pages (Columns, Relationships,
  Indexes, Constraints, Inserting & editing data, Querying & inspecting)
  with real syntax synopses; worked examples to follow.
- Surface the assistive editor on the landing page and in Getting started;
  restore cross-links now that targets exist.

Plan + STYLE updated to the five-section structure. 24 pages, build green,
links resolve, content clean; planned features carry "planned" callouts.
2026-06-10 10:40:07 +00:00
claude@clouddev1 0a343036d8 feat: compound-FK bus routing + complete V1 relationship visualization (ADR-0044)
Completes requirement V1. A compound (multi-column) FK now routes a
bus connector — each paired endpoint's stub merges into a shared
vertical channel that splits to the other side — plus an explicit
"(a, b) ▶ P.(x, y)" pairing line; the bus generalises the single-column
jog (reproducing it exactly, so prior snapshots are unchanged).
Self-referential FKs render as two same-named boxes.

- output_render.rs: gutter_seg routes all endpoint pairs via a
  junction() bus; pairing line for compound FKs; compound, self-ref,
  and compound-from-data (build_diagram_table glue) tests + snapshots
- compound_fk.rs: worker test that show_relationship carries both
  paired column lists into the diagram payload
- db.rs: document do_show_one's now-app-superseded relationship prose
  branch (retained as a worker-API/text fallback; could back a future
  non-visual display option, cf. ADR-0044 OOS-7)

Second /runda pass over the implementation: confirmed ADR-compliance,
UTF-8/byte-range safety, and edge-case routing. The ADR §3 last-resort
helper line was considered and rejected (vertical fallback + ratatui
truncation cover all realistic cases). ADR-0044 marked implemented;
requirements.md V1 -> [x].

Full suite 2207 pass / 0 fail / 1 ignored; clippy nursery clean.
2026-06-10 10:17:09 +00:00
claude@clouddev1 a0ee32393f feat: show table renders relationships as compact diagrams (ADR-0044)
show table <T> and add/drop relationship echoes now render the focal
structure box plus a Relationships section of compact stacked
connector diagrams (child-left/parent-right, n…1, actions); incidental
DDL echoes keep the prose References:/Referenced by: form. Selected by
command in handle_dsl_success via the "relationship-relevant" reach.

- output_render.rs: render_structure refactored into section helpers
  (box/prose/index/constraint), byte-identical output; new
  render_structure_with_diagrams + compact-box rendering
- app.rs: handle_dsl_success routes ShowTable/Add/DropRelationship to
  the diagram path, others to prose
- fixes: eager widths[1] index on compact (1-col) boxes; body-cell
  padding under title-widening (name wider than columns)

Tests: unit + snapshot + integration; add-relationship echo test
updated to the diagram form. Full suite 2203 pass / 0 fail / 1 ignored;
clippy clean. V1 still [/] (compound routing + self-ref remain).
2026-06-10 06:56:35 +00:00
claude@clouddev1 44390e765d feat: simple-mode code-block highlighting, prompt, and copy rules
Add a custom Shiki grammar for the simple-mode command language
(src/grammars/rdbms.mjs), registered with Expressive Code. Two language ids
share it: rdbms (real commands) and rdbms-syntax (abstract templates).
Simple-mode blocks now highlight; advanced examples keep sql.

Separation + copy ergonomics via CSS (global.css): a decorative, copy-safe
"> " prompt on rdbms command lines (not in the copy buffer), and the copy
button hidden on multi-command rdbms blocks and on rdbms-syntax templates
(the app input is single-line, so a multi-command paste is not runnable);
single-command, sql, and sh blocks keep copy.

Content: convert 22 simple-mode fences to rdbms; lead the simplest examples
(first project, Tables reference) with bare "with pk" (the beginner default
that creates a ready-made id key), pointing to the named form. Record the
fence + prompt conventions in STYLE.md.
2026-06-09 22:30:44 +00:00
claude@clouddev1 995c0ba8eb docs: reconcile website doc inventory with merged main scope
The merge from main added user-facing surface the pre-merge inventory had
listed as planned. Mark them documented-as-shipped: show tables /
relationships / indexes + show relationship/index <name> (V5/V5a),
help [<command>] + help types (H3), compound-primary-key foreign-key
references (T3, ADR-0043), and friendlier parse-error messaging (H1a).
Refresh the test count to 2193 and note requirements.md now uses a [/]
partial marker (trust the code, not the marker).
2026-06-09 22:30:44 +00:00
claude@clouddev1 cad90ec4a5 feat: show relationship <name> renders a styled two-table diagram (ADR-0044)
The first wired slice of relationship visualization (V1). `show
relationship <name>` now renders the relationship as two full
structure boxes joined by a width-jogging connector (child-left /
parent-right, n…1 cardinality, on delete/update actions), styled
App-side, with a vertical-stack fallback for narrow terminals.

- db.rs: RelationshipDiagramData + show_relationship worker path
  (structured data: the relationship + both endpoint TableDescriptions)
- runtime.rs: named relationships route to the structured outcome
  (boxed); other show <kind> forms stay prose
- app.rs/event.rs/ui.rs: DslShowRelationshipSucceeded rendered App-side;
  new diagram OutputStyleClass variants; App::last_output_width from ui.rs
- output_render.rs: styled Seg layout engine (boxes, connector routing,
  side-by-side + vertical), composing the ADR-0016 box primitives

Tests: 4 unit + 4 integration; full suite 2201 pass / 0 fail / 1 ignored;
clippy nursery clean. requirements.md V1 stays [/] (show table diagrams,
compound routing, DDL-echo wiring remain).
2026-06-09 22:27:39 +00:00
claude@clouddev1 bb02dfb752 docs: ADR-0044 relationship visualization (V1); accepted
Two-table connector diagrams (Style A) for relationships, resolving
ADR-0016 OOS-1 and the open half of requirements.md V1. Reach is
'relationship-relevant' (show relationship / show table / relationship
DDL echoes; incidental echoes keep prose). App-side rendering, width-
adaptive side-by-side vs vertical, compound-FK pair routing, bold box
title rows. Revised after a /runda DA pass corrected three inverted-
architecture claims (App-side rendering, untracked output width,
prose-in-worker show-relationship).

Index updated per ADR-0000.
2026-06-09 21:47:35 +00:00
claude@clouddev1 c72c624daa chore: bind website dev/preview server to IPv4 loopback (127.0.0.1)
Astro/Vite's default localhost bind resolves to IPv6 ::1 on this host,
which silently breaks `ssh -L 4321:127.0.0.1:4321` tunnels (they target
IPv4). Pin server.host to 127.0.0.1 so dev/preview is reachable over an
IPv4 loopback forward. Loopback-only — no network exposure.
2026-06-09 21:44:43 +00:00
claude@clouddev1 9e774b2dfa docs: ADR numbering discipline — assign numbers at merge-to-main
Codifies the fix for the ADR-0042 cross-branch collision (resolved this
merge by renumbering the website ADR to 0044): ADR numbers are assigned
when a branch merges to main, not at creation. On a branch, draft under
a placeholder (ADR-XXXX title / draft-<slug>.md filename); main's
docs/adr/README.md is the single source of truth for the next free
number.

- ADR-0000: new "Numbering discipline" section.
- CLAUDE.md: pointer to it from the documentation-discipline note.
2026-06-09 20:30:36 +00:00
claude@clouddev1 40de389bcb Merge branch 'main' into website (Gitea migration + ADR renumber)
Brings website up to date with main (18 commits): H1a parse-error
pedagogy, V5/H3/V5a show+help commands, ADR-0043 compound-PK FK,
handoffs 58-59, and the GitHub->Gitea doc scrub (Cargo.toml repository,
CLAUDE.md, ADR-0001 amendment, requirements).

Conflict: docs/adr/README.md. main and website had each created an
ADR-0042 (main: H1a parse-error pedagogy; website: public website &
docs site). Renumbered the website ADR to 0044 (next free after main's
0042/0043) and updated all references (ADR file, plan file, STYLE.md,
astro.config.mjs, README index). Website build verified green.
2026-06-09 20:28:27 +00:00
claude@clouddev1 b17148b467 docs: scrub GitHub-specifics after Gitea migration; add tea issue conventions
- Cargo.toml: repository -> git.lazyeval.net/oli/rdbms-playground
- requirements.md: backlog now tracked as Gitea issues
- ADR-0001 Amendment 1: distribution channel reopened post-migration
  (Decision text preserved per supersede-don't-rewrite)
- CLAUDE.md: issue-tracking working method + Gitea/tea operational section
2026-06-09 20:07:40 +00:00
claude@clouddev1 e9b7f58fbc docs: session handoff 59 — tracking reconciliation + V5/H3/V5a sweep + T3 compound-PK FK (ADR-0043) 2026-06-09 18:45:58 +00:00
claude@clouddev1 4752ba29a0 feat: compound-PK foreign-key references — grammar + tests (ADR-0043)
Multi-column FK parsing on both surfaces: DSL from P.(a, b) to
C.(x, y) (parenthesized endpoint; single bare form unchanged) and
SQL FOREIGN KEY (a, b) REFERENCES P(x, y) incl. bare-reference
auto-expand. consume_fk_reference + the table-level/ALTER FK
parsers collect column lists; the from P. completion now offers
( (snapshots updated). 12 integration tests in
tests/it/compound_fk.rs cover parse (both surfaces), engine-enforced
FK, arity + partial-PK + per-pair-type-mismatch refusal,
--create-fk per-column, save->rebuild round-trip, undo (one step),
and single-column preservation. Mark T3 [x]; ADR-0043 implemented.
2026-06-09 18:44:37 +00:00
claude@clouddev1 b14f0199e9 refactor: relationship model to column lists for compound FK (ADR-0043)
Move the FK column fields String->Vec<String> through all six
layers (AddRelationship/SqlForeignKey AST, RelationshipSchema,
metadata, project.yaml, ReadForeignKey, RelationshipEnd). Metadata
stores comma-joined lists in the existing TEXT cells; project.yaml
endpoints now columns: [a, b] (house style). Executor logic is
multi-column ready: resolve_fk_parent_columns (full-PK F-A +
auto-expand F-D), per-pair type-compat, schema_to_ddl multi-column
emission, pragma FK read grouped by id, auto-name + --create-fk
per-column, multi-column teaching echo. Single-column behaviour
preserved (one-element vecs); all 2181 tests green. The grammar to
parse multi-column input lands next.
2026-06-09 18:25:40 +00:00
claude@clouddev1 b688592b4c docs: ADR-0043 implementation-readiness notes from /runda DA pass
DA pass found three change sites the first sketch missed
(teaching-echo renderers, --create-fk per-column creation, the
auto-name generator) and made explicit the rules the forks left
implicit: SQLite FK precondition (compound PK provides the unique
index), explicit parent cols must be the PK set (any order,
positional), arity/empty/inline-rejection wording, single-in-parens
accepted, --create-fk per-column typed to fk_target_type. Expanded
the test plan to cover enforcement, auto-expand, undo, round-trip.
Fixed a stale 'legacy yaml loads' test line (no back-compat).
2026-06-09 17:11:01 +00:00
claude@clouddev1 274e2b17b7 docs: ADR-0043 compound-PK foreign-key references (T3); accepted
Audit found single-column FK woven through ~15-20 sites; earns an
ADR. Decision: reference the parent's full compound PK, matched
positionally to an equal-length child list, per-pair type compat.
DSL `from P.(a,b) to C.(x,y)`; SQL `FOREIGN KEY (x,y) REFERENCES
P(a,b)` with bare-FK auto-expansion. Storage follows the existing
primary_key: [...] list convention (yaml columns: [a,b], uniform
JSON in unchanged metadata TEXT cols); back-compat not required,
so no migration. Also marks T3's verified scope.
2026-06-09 17:01:38 +00:00
claude@clouddev1 1d898adf00 feat: V5a show relationship/index <name> detail views
Fold the singular per-item forms into Command::ShowList { kind,
name: Option<String> } (name: Some = one item). Two grammar
branches reuse the relationship/index completion sources; worker
do_show_one renders a labelled detail block or a friendly
"No ... named X." line, reusing the V5 render path. Help +
parse-usage entries, two ADR-0042 near-miss rows, 5 integration
tests. Mark V5a [x] — V5's [<name>] clause now complete.
2026-06-07 14:04:00 +00:00
claude@clouddev1 757711f2bf feat: H3 help <command> per-command detail + general reference
HELP node takes an optional single-word topic (BarePath);
AppCommand::Help { topic }. note_help_topic renders the help
block(s) of every command sharing that entry word (so `help
create` covers both create forms), plus `help types` and a
friendly "no help for X" pointer for unknown topics. Full help
gains a detail-hint footer. Catalogued help.detail_hint /
help.unknown_topic; parse-error matrix updated (help now takes a
topic, so the near-miss is the multi-word case). 9 integration
tests in tests/it/help_command.rs. Mark H3 [x].
2026-06-07 13:32:18 +00:00
claude@clouddev1 8dec784080 feat: V5 show tables / relationships / indexes list commands
Add the list-all show family as one Command::ShowList { kind }
variant. A read-only worker show_list formats count-headed lists
(reusing do_list_tables / read_all_relationships /
read_table_indexes, so it never drifts from the items panel);
internal __rdbms_* tables excluded. Help + parse-usage entries
added; 10 integration tests in tests/it/show_list.rs.

Mark V5 [x]. Split the singular show relationship/index <name>
detail forms (the [<name>] half) into a new tracked V5a [ ] item
rather than leaving them as an untracked footnote.
2026-06-07 13:20:52 +00:00
claude@clouddev1 28e75961aa docs: reconcile requirements tracking with verified code state
Audit of all 35 [ ] items vs source found ~46% mis-marked. Add a
[/] partial marker; promote 7 shipped-but-open items to [x]
(S1/S4/S5/I1a/I3/I4/C1) and 9 substantially-built ones to [/]
with gap notes (S3/A1/V1/V2/V5/T3/H3/DOC1/X1). Fix CLAUDE.md's
false "Tier 4 is wired" claim — no PTY tests exist.
2026-06-07 12:31:16 +00:00
claude@clouddev1 ca158e8b25 docs: session handoff 58 — H1a done via ADR-0042 systematic pass 2026-06-06 12:29:47 +00:00
claude@clouddev1 c305dc7282 docs: mark H1a done via the ADR-0042 systematic pass
requirements.md H1a → [x]: the per-command near-miss matrix (entry words,
missing clauses, committed multi-forms, both modes) plus the gap fixes
(G1 `1:n relationship`, G2 select projection gloss, G3 mode-aware usage
showing all valid forms, G4 `with` CTE template, CROSS JOIN ON teaching
message) close the systematic pass. The advanced-SQL items the survey
flagged (INSERT…SELECT count, RETURNING scope) were verified already
present. One low-priority residual is deferred by decision (submit-time
expression first-set at non-projection positions).

ADR-0042: record the pre-existing `SELECT *` arity caveat (INSERT…SELECT
with a star projection isn't expanded for pre-flight arity; engine
catches it at execution — adjacent to ADR-0019 §OOS-2).
2026-06-06 07:44:55 +00:00
claude@clouddev1 0fcb7b1105 docs: website docs structure + first content pages
Phase D foundation. Configures the pragmatic four-section sidebar
(Getting started / Guides / Reference / Concepts) and replaces the
template example pages with grounded content built on the shared
"library" example database (authors/books/members/loans):

- Getting started: installation, first project, simple vs advanced,
  the example library.
- Reference: Types (all ten + serial/shortid + advanced aliases),
  Tables (create/drop, compound PK, advanced CREATE TABLE).
- Concepts: projects & storage (readable files, derived database,
  autosave, temp projects).
- Guides: Build the library (draft, to be refined for teaching).

Command syntax grounded in en-US.yaml usage/help, command.rs, and
types.rs (verified against tests). Records the settled doc decisions
in STYLE.md. Build green (10 pages, Pagefind); content clean of
"DSL"/engine-name.
2026-06-06 07:34:57 +00:00
claude@clouddev1 d6e229f0f5 feat: H1a CROSS JOIN ON teaching message; advanced-SQL gaps re-verified (ADR-0042)
Empirically re-checking ADR §3's advanced-SQL "gaps" reversed two of
three — the code survey that produced the list was wrong:
- INSERT…SELECT column-count: already handled (verdict=Error, "the
  column list names N column(s) but M value(s) are given";
  insert_select_arity_mismatch_fires).
- RETURNING scope: already handled (completion offers the table's
  columns; `returning <unknown>` → unknown_column diagnostic).

The one genuine residual is fixed: `select … cross join b on …`
rejected the ON with a bare "expected end of input". Add
parse.cross_join_no_on — "a CROSS JOIN has no ON clause — it pairs
every row; for a join condition use `JOIN … ON`, or filter with
`WHERE`" — rendered when the failing token is `on` and the most
recent consumed join is a CROSS join (a precise signature: every
other join requires `on`, so `on` is expected there, not a failure).
Render-only in format_walker_error; two misfire guards locked (plain
join still asks for ON; a stray `on` with no join does not fire).

ADR-0042 §3 corrected + Implementation-outcome records the advanced-SQL
re-check and the user-confirmed low-priority residual (submit-time
expression first-set at non-projection positions, where typing-time
completion already offers the right candidates).

Full suite green (lib 1578 / it 388 / typing_surface_matrix 192); clippy clean.
2026-06-05 19:02:11 +00:00
claude@clouddev1 1d4923b15b fix: H1a G3 advanced usage shows all valid forms; complete near-miss matrix (ADR-0042)
The /runda DA pass found G3 over-corrected: advanced-mode `create`/`drop`
showed SQL forms only, hiding the DSL fallback forms that are valid input
in advanced mode (verified: `create table Foo with pk`, `drop column …`
parse and dispatch). Per the user decision, the advanced usage block now
shows every form valid in the mode, SQL-primary first, then the DSL
fallback forms — a usage hint must never hide working input. Simple mode
unchanged (DSL forms only).

Matrix completion (closing the residual coverage tail):
- arg-less app commands (help/rebuild/new/load/undo/redo/export/import)
  audited + locked — all reject trailing junk with "expected end of
  input" + usage.
- committed multi-forms (add index/constraint/1:n relationship, drop
  index/constraint/relationship, show table, change column, create index,
  alter table add/drop) audited + locked in
  near_miss_matrix_committed_multiforms — each renders its own
  form-specific missing-keyword message + usage.

Also from the DA pass:
- G2 distinct+all detector empirically verified unique to projection
  start (no misfire at count( / union / union all / select distinct).
- stale `chumsky` comment removed (app.rs import handler).
- ADR-0042 Implementation-outcome section records G1–G4, the
  user-confirmed G3 decision, and the now-complete matrix coverage.

Full suite green (lib 1578 / it 387 / typing_surface_matrix 192); clippy clean.
2026-06-05 18:46:57 +00:00
claude@clouddev1 cea99e8b70 chore: scaffold website (Astro 6 + Starlight + Tailwind v4)
Phase A of docs/plans/20260604-adr-0042-website.md. Scaffolds the site
under website/ from the Starlight template; adds Tailwind v4 (via
@tailwindcss/vite) bridged to Starlight with @astrojs/starlight-tailwind
(src/styles/global.css + customCss). Production build is green: static
output, Pagefind search index, sharp image optimization.

Template placeholders (title, example pages, sidebar) are left for
Phase B/D. Reconciles the ADR/plan/index wording from "Astro 5" to
"Astro 6" to match the scaffolded toolchain.
2026-06-05 15:00:12 +00:00
claude@clouddev1 649fdcb38e feat: H1a parse-error gaps G2–G4 + advanced near-miss matrix (ADR-0042)
Close the three remaining ADR-0042 triage gaps, each test-first, and
lock the advanced-mode near-miss matrix.

G2 — bare `select` dumped the 14-item expression first-set. Collapse
it to "a projection: `*`, a column, or an expression" in the error
message only (parser::format_walker_error), detected by the joint
`distinct`+`all` quantifier signature unique to a projection start.
Render-only: completion/hints still expand the full set (typing-surface
matrix unchanged).

G3 — the usage block was mode-blind: advanced `create table` showed the
DSL `create table … with pk …` template. usage_key(s)_for_input gain
mode-aware `_in_mode` variants selecting candidates by CommandCategory;
render_usage_block and the typing-time ambient usage thread the
submission mode. Advanced `create` now shows both SQL forms. A fallback
covers shared SQL nodes (insert/update/delete) that declare no
usage_ids of their own — without it they regressed to the
available-commands fallback (caught by the new advanced matrix).

G4 — `with` borrowed `select`'s usage template; give it its own
parse.usage.with CTE template.

Tests: new near_miss_matrix_advanced_mode (12 SQL-surface cases incl.
the available-commands regression guard) + per-gap tests; removed the
temporary baseline_dump. Full suite green (lib 1578 / it 386 /
typing_surface_matrix 192); clippy clean.
2026-06-05 14:57:20 +00:00
claude@clouddev1 1fad29c0f9 docs: ADR-0042 — public website + documentation site plan
Planning artifacts for the first public website, recorded before any
code is written.

- ADR-0042: the decisions — Astro 5 + Starlight + Tailwind v4 (over
  SvelteKit); asciinema .cast demos reusable in docs (scripted-input
  driver, not history.log replay); in-page WASM playground deferred
  behind a stable demo seam, with the portable-core vs native-edge
  boundary recorded for a future ADR; portable static hosting (Vercel
  target); monorepo (website/); website is the canonical docs home;
  full-feature-set docs with "planned" callouts; user-facing copy uses
  no engine name and no "DSL"; install via prebuilt binaries + package
  managers.
- docs/plans/20260604-adr-0042-website.md: implementation plan with the
  grounded documentation inventory and phases A–E.
- website/STYLE.md: living documentation style guide + open-decisions log.
- docs/adr/README.md: index updated for ADR-0042 (numerical order).
2026-06-05 08:13:36 +00:00
claude@clouddev1 10f8c2a95c test: H1a near-miss matrix + friendlier add 1:n relationship label (ADR-0042)
Start the ADR-0042 §1 near-miss matrix: a table-driven
near_miss_matrix_simple_mode locking 26 simple-mode parse-error
renderings (every DSL entry word's bare/missing-clause cases plus the
mode arg-errors and the "this is SQL" rail), and an #[ignore]
baseline_dump capturing the full rendering for ongoing triage.

G1 fix: the bare `1` cardinality literal that opens `add 1:n
relationship …` rendered cryptically in expected-sets. Render it as
`1:n relationship` in error wording only (format_expectation) —
completion/hints still read the raw Expectation::Literal("1"), so the
candidate surface is unchanged. Updated the one anchor test.

Full suite green (lib 1578 / it 382 / typing_surface_matrix 192).
2026-06-05 08:04:24 +00:00
claude@clouddev1 0e6f767848 docs: ADR-0042 — continue H1a parse-error pedagogy on the grammar tree
ADR-0020/0021 specified a chumsky-based H1a; ADR-0024 replaced chumsky
with the scannerless walker, leaving both obsolete. Mark them superseded
(kept as institutional memory) and add ADR-0042, which restates H1a
against the architecture as built.

ADR-0042 records that H1a is substantially shipped already — per-command
usage block, available-commands fallback, source-derived ident slot
labels, curated parse.custom.* near-miss messages, and schema-aware
[ERR] diagnostics — and defines the remaining work: a verified
per-command near-miss matrix (the definition of done), friendlier
literal expectation labels that add role context while keeping the
exact literal visible, and advanced-mode SQL parse parity (RETURNING
scope, CROSS JOIN ON, INSERT…SELECT count), kept distinct from
ADR-0019 §OOS-2 engine-error sanitisation.

- docs/adr/0020,0021: superseded notes + README entries
- docs/adr/0042: new ADR
- docs/adr/README.md: index upkeep (ADR-0000 rule)
2026-06-03 14:05:09 +00:00
claude@clouddev1 a8d0138d8b docs: session handoff 57 — H1 verified done, target/ 38 GB → 1.6 GB, tests consolidated
Captures the post-handoff-56 arc: H1 (ADR-0019) verified already shipped
(not "partial"); build-hygiene fixes (incremental off, line-tables debug,
cargo-sweep) cutting target/ from 38 GB to ~1.6 GB; and consolidating 25
integration crates into one `it` binary (disk win, not the predicted
speed win). Flags the new test layout (add tests under tests/it/ + a mod
line) and points the next session at H1a (ADR-0021) as the queued job.
2026-06-02 22:17:06 +00:00
claude@clouddev1 9efae59c3c test: consolidate 25 integration crates into one it binary
Each top-level tests/*.rs was its own crate → its own binary, each
statically linking the bundled engine + every dep. 26 of them, so an
edit to the lib relinked all 26. Moved the 25 standalone files into
tests/it/ under one tests/it/main.rs (the pattern typing_surface
already uses); cargo auto-detects it as the `it` target. End state: 2
integration-test binaries instead of 26.

Result: target/debug/deps 1.5 GB → 629 MB (-58%). Build time barely
moved (clean 22.9s→22.4s, lib-edit relink 13.3s→12.4s) — wall-clock is
dominated by compiling, not linking, so this is a disk win, not a speed
win (see docs/plans/20260602-test-consolidation.md). Tests unchanged at
2151/0/1; clippy clean; no fixups needed. typing_surface_matrix stays
its own already-consolidated binary.

Tradeoff: the 25 files now share one crate (a compile error fails the
whole `it` binary; module-scoped namespaces, no clashes) — negligible
for a solo project.
2026-06-02 22:13:03 +00:00
claude@clouddev1 42f95533ac chore: bound target/ growth — incremental off, line-tables debug
target/ had reached 38 GB, dominated by a 16 GB incremental cache
(~28 compilation units × every historical config, never evicted) and
~25 separate integration-test binaries each statically embedding the
bundled engine + full debug info.

[profile.dev] (inherited by the test profile):
- incremental = false: the cache earns little in a full-suite workflow
  and never self-evicts; off, target/ stays bounded.
- debug = "line-tables-only": keeps file:line in panics/backtraces (we
  debug via tracing logs) at a fraction of debug=2's size.

Net: a clean full build dropped from 38 GB to ~1.6 GB. Document the
rationale plus the cargo-sweep workflow (the GC cargo lacks) under a
new CLAUDE.md "Build hygiene" section; also drop the now-shipped H1
from CLAUDE's deferred list (H1a remains).
2026-06-02 20:07:54 +00:00
claude@clouddev1 be7b078878 docs: mark H1 done — friendly DB-error layer is shipped
Verification found H1 (ADR-0019) fully implemented and tested: the
friendly::translate_error chokepoint is wired on the live failure path
(runtime + app + DbError::friendly_message), covers all five error
categories (UNIQUE, FOREIGN KEY both sides, NOT NULL, CHECK,
type-mismatch) with operation×kind×verbosity wording, the messages
verbosity command, and §6 row-pinpointing via runtime-resolved facts —
backed by 44 friendly unit tests + 12 full-stack friendly_enrichment
integration tests. The "partial / FK-only" notes were stale.

Mark requirements H1 done; fix the obsolete "diagnostic_table is
always None" comment in translate.rs (pinpointing landed in 431645a).
Remaining ADR-0019 scope (§9 i18n sweep, §OOS-2 advanced-SQL
sanitization, §OOS-3 messages persistence) stays deferred.
2026-06-02 20:07:45 +00:00
claude@clouddev1 56d9671488 docs: session handoff 56 — serde_norway migration clears RUSTSEC-2025-0067/0068 2026-06-02 14:34:39 +00:00
claude@clouddev1 9e2372b039 fix: migrate off unsound serde_yml to serde_norway
serde_yml (RUSTSEC-2025-0068) and its libyml backend
(RUSTSEC-2025-0067) are archived, unsound, and unmaintained with no
patched version. Swap to serde_norway, the maintained serde_yaml fork
on unsafe-libyaml-norway — a drop-in for our from_str / to_string /
Value usage across persistence, undo, and the catalog parser.

Clears both advisories (cargo audit / osv-scanner / grype all clean;
serde_yml + libyml gone from the tree). No behaviour change; full
suite 2151/0/1.
2026-06-02 14:34:34 +00:00
claude@clouddev1 c9a92c9c20 docs: session handoff 55 — #11 resolved, ADR-0041 + arboard dep 2026-06-02 14:23:26 +00:00
claude@clouddev1 d0c8f9d5d2 feat: copy the output panel to the system clipboard (#11)
New app-level `copy` / `copy all` / `copy last` command (ADR-0041).
Delivery is OSC 52 *and* a best-effort native write (arboard), always
both — OSC 52 acceptance is undetectable, so a true fallback can't be
built. Payload is the panel's plain text exactly as rendered (tags,
✓/✗, box-drawing), drift-locked to render_output_line. arboard added
--no-default-features (X11-only; OSC 52 covers Wayland).

Amends ADR-0003's command registry; requirements V6.
2026-06-02 14:23:21 +00:00
claude@clouddev1 1ea376be26 docs: session handoff 54 — #10/#14 resolved, ADR-0037 Am1 + ADR-0015 Am1
#10 (output [error]/[system] tag-colour collision) and #14 (per-project
input-mode persist & restore) closed. Two ADR amendments authored.
Records the two /runda saves on #14 (persist semantics re-decided by the
user; missing integration test added red-first) and a detailed pickup
brief for #11 (clipboard — new dependency, security review + command
surface to escalate).
2026-06-02 08:11:01 +00:00
claude@clouddev1 516848ff63 test: integration-test the mode persist-on-unload wiring (#14)
The post-/runda DA pass on 4cd574b found the persist-on-unload wiring
(quit + project switch calling Database::set_mode) had no integration
test — only the db-level set_mode behaviour was covered, not that the
runtime actually invokes it on unload.

Add runtime::switch_persists_the_outgoing_projects_mode, driving the
real handle_project_switch end-to-end and asserting the outgoing
project's project.yaml recorded the mode it was left in. Red-first
verified: with the set_mode call disabled it fails (None vs
Some(Advanced)). The quit unload site shares the same set_mode call;
Action::Quit emission is already covered in app tests.

Updates ADR-0015 Amendment 1 coverage note.
2026-06-02 08:06:48 +00:00
claude@clouddev1 4cd574b909 feat: persist & restore per-project input mode (#14)
The input mode always started in simple; a learner who quit in advanced
had to re-toggle every launch. Store the mode per-project in project.yaml
(project.mode:, optional, default simple) and restore it on every open.

Mode is live UI state, not schema: the worker stamps the current mode
into project.yaml on every write, so a later command rewrites the live
value rather than clobbering it — no db round-trip needed. The mode is
persisted on unload (quit + project switch) so the mode you leave a
project in is always what reopens; the `mode` command also persists
immediately. A switch saves the outgoing mode, then restores the
incoming project's stored mode.

New --mode simple|advanced CLI flag (precedence --mode > stored >
simple; combines with --resume). A teacher can ship a project that
opens in advanced mode and export it to students (the mode travels in
the zip).

ADR-0015 Amendment 1; ADR-0003 note; help banner; requirements L1b.
2026-06-02 06:47:34 +00:00
claude@clouddev1 ae57c6fc82 feat: colour output tags by status, not mode — readable error bodies (#10)
The output tag was tinted by submission mode for every line kind, so a
[system] line and an [error] line rendered with an identical leftmost
tag — distinguishable only by body colour. And flooding the whole error
body in red made long messages hard to read.

Colour the tag by message status instead (its OutputKind): [system] →
green, [error] → red; the echo tag keeps the mode tint (ADR-0037's
actual purpose — per-command success rides the ✓/✗ marker). Bodies go
neutral; the error body stays bold for weight (rustc-style: severity-
coloured label, readable bold message). Yields a status traffic-light
matching the ✓/✗ palette.

Narrows ADR-0037's mode side-channel to the echo line it was always for.
ADR-0037 Amendment 1; closes the tag-colour gap ADR-0040 flagged as OOS.
2026-05-31 22:02:12 +00:00
claude@clouddev1 1a93f0cd01 docs: session handoff 53 — #15/#16 resolved, ADR-0022 Amendment 6 2026-05-31 16:28:42 +00:00
claude@clouddev1 6d8c9eea36 feat: curated SQL function list — Tab completion (#15) + typing-time typo hint (#16)
Add src/dsl/sql_functions.rs (KNOWN_SQL_FUNCTIONS) as the shared source
of truth at sql_expr_ident slots:

- #15: offer the functions as Tab candidates under a new
  CandidateKind::Function + ninth Theme colour tok_function (blue,
  distinct from keyword/identifier/type).
- #16: restore the column-typo flag the #6 fix had dropped wholesale —
  invalid_ident_at_cursor now bails only when the partial prefix-matches
  a known function, else falls through to the schema-column check.

A column named like a function (e.g. `count`) is deduped (column wins).
`cast` is excluded — CAST(x AS type) is not a plain-call shape.
The no-validation-allowlist posture stands: the list drives completion +
the typo hint only, never parse-time acceptance.

Docs: ADR-0022 Amendment 6, ADR-0031 status note, README index,
requirements I3/I4 + refreshed test baseline.
2026-05-31 11:49:10 +00:00
claude@clouddev1 01ec926ec8 docs: session handoff 52 — #8/#13/#12/#7/#9 resolved, ADR-0039 impl + ADR-0040 2026-05-30 21:48:58 +00:00
claude@clouddev1 8311de44a8 feat: replace the [ok] summary line with a ✓/✗ echo marker
An audit of the command surface found the `[ok] <verb> <subject>`
summary line duplicated the echo line above it everywhere; its only
unique signal was success-vs-error. Retire it: a command's echo line
now resolves from `running: <input>` to `<input> ✓` / `<input> ✗`
on completion, and the symmetric `"<verb> <subject>" failed:` prefix
is dropped (only the reason remains). Content lines (row counts,
structure, plan tree, teaching echo) are unchanged.

Echo lines carry an EchoStatus; executed commands push Pending and
resolve the oldest-pending echo on their result event (FIFO worker —
correct under interleaving). Parse-time and pre-flight rejections are
not executed and keep their running: + caret rendering. App-command
[ok] lines (rebuild/export/replay) are payload-bearing and untouched.
ADR-0040.
2026-05-30 21:38:48 +00:00
claude@clouddev1 f62cccec55 feat: support explain over advanced-mode SQL queries
explain now wraps the advanced SQL commands — select, with (CTE),
insert, update, delete — in addition to the DSL show data/update/
delete it already covered, rendering through the same plan tree
(ADR-0039, closing the ADR-0030 OOS-2 gap).

Implemented as a second Advanced `explain` CommandNode under the
shared entry word, reusing the established shared-word dispatch
(SQL-first, DSL-fallback) rather than new grammar machinery.
build_explain_sql slices the inner SQL off the source and reuses the
existing SQL builders; do_explain_plan runs EXPLAIN QUERY PLAN over
the carried text verbatim (never executes, so safe for destructive
verbs). Advanced explain update/delete now route through SQL with an
identical plan; DSL-explain tests pinned to simple mode. Help and
usage text now list the advanced explain forms.
2026-05-30 18:44:05 +00:00