docs(adr-0005): Amendment 2 — drop blob from the type vocabulary
blob is a dead-end type: no literal in either mode, seed-unsupported, so a blob column can only ever hold NULL. It rode along as the engine's fourth storage class and never got the pedagogical scrutiny UUIDs (excluded) and compound PKs (defended) received — and there's nothing natural to do with binary data in a TUI teaching tool. Drop it → a nine-type vocabulary. Records the removal scope (Type::Blob + Value/CellValue::Blob + the base64 CSV path + completion/grammar slot + the help/hint user-facing strings + the binder refusal, whose message also carried a "DSL" copy-rule bug subsumed by deletion) and the backward-compat migration: the ADR-0015 framework's first real use — a v1→v2 migrator converts type: blob → text and forces a .db rebuild from the migrated text. convert-to-text chosen over drop-the-column (CSV rewrites) and refuse-to-load. Updates the ADR index.
This commit is contained in:
+1
-1
@@ -17,7 +17,7 @@ This directory contains the project's ADRs, recorded per
|
||||
- [ADR-0002 — Database engine](0002-database-engine.md)
|
||||
- [ADR-0003 — Input modes and command dispatch](0003-input-modes-and-command-dispatch.md) — the persistent `Simple`/`Advanced` mode and the `:` one-shot escape. The **startup mode is no longer always `simple`**: it is restored from the project's stored mode and overridable with `--mode` (see **ADR-0015 Amendment 1**, issue #14). The app-command registry gains **`copy`** (ADR-0041, issue #11)
|
||||
- [ADR-0004 — Project file format](0004-project-file-format.md)
|
||||
- [ADR-0005 — Column type vocabulary](0005-column-type-vocabulary.md) — the ten-type set (`text`/`int`/`real`/`decimal`/`bool`/`date`/`datetime`/`blob`/`serial`/`shortid`), compound PKs, no true UUIDs; `decimal` stored as exact TEXT. **Amendment 1, 2026-06-12** (issue #32): SQLite has no native decimal/BCD type, so arithmetic/aggregation over a TEXT `decimal` is implicitly coerced to an IEEE-754 double and the computed (typeless) result leaked float noise (`298.59999999999997` for `298.60`); floating-point values are now rounded to **15 significant figures for display only** (`format_real_display` in `db.rs`, wired into `format_cell` — the result-set/`show data` cell formatter, the only surface where arithmetic noise surfaces) while every other f64→string path keeps full precision because the distinction is *semantic*: persistence (`csv_io::format_real`) stays byte-exact for round-trip; `render_value` is a *canonical identity key* for the uniqueness dry-runs (`dry_run_unique` ADR-0029 §5, `check_uniqueness_collisions` ADR-0017 §4.3) so rounding it would report collisions the exact-valued engine wouldn't; FK-key matching and EXPLAIN-SQL literals likewise stay exact — so stored `real`/`decimal` round-trips stay byte-exact and raw `decimal` columns render verbatim
|
||||
- [ADR-0005 — Column type vocabulary](0005-column-type-vocabulary.md) — the ten-type set (`text`/`int`/`real`/`decimal`/`bool`/`date`/`datetime`/`blob`/`serial`/`shortid`), compound PKs, no true UUIDs; `decimal` stored as exact TEXT. **Amendment 1, 2026-06-12** (issue #32): SQLite has no native decimal/BCD type, so arithmetic/aggregation over a TEXT `decimal` is implicitly coerced to an IEEE-754 double and the computed (typeless) result leaked float noise (`298.59999999999997` for `298.60`); floating-point values are now rounded to **15 significant figures for display only** (`format_real_display` in `db.rs`, wired into `format_cell` — the result-set/`show data` cell formatter, the only surface where arithmetic noise surfaces) while every other f64→string path keeps full precision because the distinction is *semantic*: persistence (`csv_io::format_real`) stays byte-exact for round-trip; `render_value` is a *canonical identity key* for the uniqueness dry-runs (`dry_run_unique` ADR-0029 §5, `check_uniqueness_collisions` ADR-0017 §4.3) so rounding it would report collisions the exact-valued engine wouldn't; FK-key matching and EXPLAIN-SQL literals likewise stay exact — so stored `real`/`decimal` round-trips stay byte-exact and raw `decimal` columns render verbatim; **Amendment 2, 2026-06-22** (supersedes the `blob` row): drops `blob` from the vocabulary → a **nine-type** set. `blob` was a dead-end — no literal in either mode (ADR-0014/0038), `seed`-unsupported (ADR-0048), so a blob column could only ever hold NULL; it rode along as the engine's fourth storage class and never got the pedagogical scrutiny UUIDs (excluded) and compound PKs (defended) did, and there is nothing natural to *do* with binary data in a TUI teaching tool. Removes `Type::Blob` + `Value::Blob`/`CellValue::Blob` + the base64 CSV path + the completion/grammar `BLOB_SLOT` + the `help types`/`value_slot_blob` user-facing strings + the binder's blob refusal (whose message carried a "DSL" copy-rule bug — subsumed by deletion); simplifies ADR-0017's type-change matrix (`↔ blob` static refusals vanish) and the seed generator; `base64` stays (clipboard OSC-52). **Backward compat = the migration framework's (ADR-0015) first real use**: a v1→v2 migrator rewrites `type: blob`→`type: text` in `project.yaml` (re-versioning every project once, `.bak` written) and forces a `.db` rebuild from the migrated text when a column actually changed (the stale `.db` keeps a `STRICT … BLOB` engine column + `"blob"` metadata that load uses as-is); **convert-to-text** chosen over drop-the-column (drop would force CSV rewrites past the strict header check — not worth it) and refuse-to-load; non-destructive + PK/FK-safe + CSV-free. Knocks `ten-type`→`nine-type` across ADR-0030/0033/0035, `CLAUDE.md`, website type reference
|
||||
- [ADR-0006 — Undo snapshots and replay log](0006-undo-snapshots-and-replay-log.md) — **Accepted**. The **replay/journal half** (U3/U4) shipped via ADR-0034; the **undo/snapshot half** (U1/U2) is settled by **Amendment 1 (2026-05-24)** and **implemented 2026-05-24** (plan: `docs/plans/20260524-adr-0006-undo-snapshots.md`; ring in `src/undo.rs`, worker hook in `src/db.rs`). Amendment 1 **supersedes the original "snapshots only before destructive operations" model**: a snapshot is taken before **every** data/schema mutation (DSL + SQL) for familiar single-step (Ctrl-Z) undo — so the confirmation collapses to *naming the one command being undone* (no db-diff). Snapshot is a **hybrid whole-project copy** — database via the online backup API **plus** `project.yaml`/`data/*.csv` as files — reconciling this ADR with ADR-0015's "text is authoritative, db is derived"; undo restores all three directly. Staged before the mutation's transaction, finalised after the db commit (preserves ADR-0015 §6 commit-db-last); rolled-back ops leave no snapshot. **Persisted** ring under `.snapshots/`, **N = 50** (raised from 10), git-ignored + export-excluded + temp-cleanup-aware. `redo` supported, **redo stack discarded on new work**. **Batch ops record one undo step** (`replay` + future batch via a Begin/EndBatch worker primitive); **`import` is outside undo** (it switches projects per ADR-0015 §11, leaving the current project untouched). A **`--no-undo` CLI flag** disables snapshotting (hardware escape hatch). Adds the `backup` feature to `rusqlite`
|
||||
- [ADR-0007 — Sharing and export](0007-sharing-and-export.md)
|
||||
- [ADR-0008 — Testing approach](0008-testing-approach.md) — the four-tier strategy (pure-logic units → `TestBackend` render/`insta` snapshots → synthetic event-loop integration → PTY black-box). **Amendment 1 (2026-06-22): Tier 4 realized (TT4).** `tests/e2e_pty.rs` drives the actual built binary in a real pseudo-terminal — `portable-pty` + `vt100`, **`expectrl` dropped** (conflicting PTY layer; replaced by a hand-rolled `wait_for` on the vt100 grid). Fixed 100×30, per-test temp `--data-dir`, serial, tight fail-fast 3 s waits; table presence read from the Tables **sidebar** region (the Output panel echoes commands); commands **paced to completion** (a command sent mid-rebuild can misparse against a stale schema cache, issue #39). The four flows: cold-launch→DDL→quit; create→reopen (`--resume`, column round-trips); export→import→rebuild (schema **+** data); undo-after-DROP through the modal. Runs by default in `cargo test` → the Linux gate exercises it (**advances TT5**); PTY-in-container validated; Windows execution + nightly broader coverage stay out of scope. Also piggybacks NFR-1/NFR-3 measurement (ADR-0057)
|
||||
|
||||
Reference in New Issue
Block a user