blob was a dead-end: declarable but never fillable (no literal in either mode, seed-unsupported), so a blob column could only ever hold NULL. Remove Type::Blob + Value/CellValue::Blob + the base64 CSV path + the grammar slot + completion/render/type-change/seed handling + the binder refusal (whose message also carried a user-facing "DSL" copy-rule bug). The vocabulary is now nine types; base64 stays (clipboard OSC-52). Backward compat is the ADR-0015 migration framework's first real use: a v1->v2 format bump (CURRENT_SCHEMA_VERSION across serializer/parser/skeleton) with a migrator that rewrites `type: blob` -> `type: text`, and a forced .db rebuild from the migrated text when a blob column was actually converted (the stale .db keeps a STRICT BLOB engine column). Conversion to text is non-destructive and CSV-free. Covered by a full-stack integration test and a Tier-4 PTY test that opens a real legacy v1-blob project. Also sweeps the nine-type vocabulary through CLAUDE.md, requirements.md, the website (type reference, seed doc, highlight grammar), and the ADR-0030/0033/ 0035 cross-references; CHANGELOG Removed entry; handoff-79. BREAKING CHANGE: the `blob` column type is removed. Existing projects that declared a blob column are migrated on first open (the column becomes text; the original project.yaml is kept as a .v1.bak).
108 lines
6.4 KiB
Markdown
108 lines
6.4 KiB
Markdown
# Session handoff — 2026-06-22 (79)
|
|
|
|
A long session continuing the open-issue sweep (handoff-77/78). Cleared the
|
|
**help** issue (#36) and the **schema-cache** bug (#39) earlier; this note
|
|
mainly records the big piece: **dropping the `blob` column type** (ADR-0005
|
|
Amendment 2), which grew out of a one-line copy-rule fix.
|
|
|
|
## §1. State
|
|
|
|
**Branch `main`.** Commits this session so far (all on `main`, **not pushed**):
|
|
`07575da` (#39 gate) · `e88fa79` (handoff-77 + changelog rule) · `3ad4aff`
|
|
(#36 help) · `64818c0` (handoff-78) · `1a2002d` (**ADR-0005 Amendment 2** —
|
|
the blob-drop decision record).
|
|
|
|
**Uncommitted: the blob-removal implementation** (39 files) — staged for review,
|
|
commit proposed at session end (see §4). **Full suite green: 2520 passed / 0
|
|
failed / 1 ignored** (1810 lib + 7 e2e_pty + 503 it + 200 typing).
|
|
`clippy --all-targets -D warnings` + `fmt --check` clean.
|
|
|
|
**Closed this session:** #36, #39. **Open:** #37 (clause hints), #38
|
|
(diagnostic route — needs a do/defer/close call), #40 (winget release notes).
|
|
|
|
## §2. What shipped — drop `blob` (ADR-0005 Amendment 2)
|
|
|
|
**Why** (recorded in the ADR): `blob` was a dead-end type — declarable but
|
|
never fillable (no literal in either mode, `seed`-unsupported), 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. The vocabulary is now **nine types**.
|
|
|
|
**Discovered via:** the `value.rs:106` binder message *"…not supported in DSL
|
|
yet"* — a user-facing copy-rule violation (it `passthrough`es to the user via
|
|
`DbError::InvalidValue`). Rather than reword, we removed the type; the message
|
|
is deleted outright.
|
|
|
|
**Implementation (test-first throughout):**
|
|
- **Removal** (compiler-guided): `Type::Blob` + its `keyword`/`sqlite`/`all()`/
|
|
`from_sql_name` alias arms; `Value::Blob`; `CellValue::Blob(Vec<u8>)` + the
|
|
base64 CSV encode/decode; the `BLOB_SLOT` grammar slot; completion's `blob`
|
|
candidate; `output_render`'s `BLOB`; the type-change `↔ blob` static refusal;
|
|
the seed blob arms; the binder refusal. User-facing strings: dropped `blob`
|
|
from `help.types_reference` and removed the `hint.value_slot_blob` slot hint.
|
|
`base64` **stays** (clipboard OSC-52).
|
|
- **Backward-compat migration** (the ADR-0015 framework's **first real use**):
|
|
a **v1→v2 format bump**. `parse_schema` hard-pinned the version to 1, so this
|
|
rippled into a `CURRENT_SCHEMA_VERSION = 2` constant used by the serializer +
|
|
parser + skeleton, the first registered migrator (`migrate_v1_to_v2`:
|
|
rewrites `type: blob`→`type: text` + bumps the version), and ~30 `version: 1`
|
|
test fixtures. The runtime (already wired to `ensure_project_yaml_migrated`)
|
|
**forces a `.db` rebuild** from the migrated text **only when a blob column
|
|
was actually converted** (`body_declares_blob_column` pre-read at both open
|
|
sites) — the stale `.db` keeps a `STRICT … BLOB` engine column + `"blob"`
|
|
metadata it would otherwise use as-is. Conversion target **text** (not drop)
|
|
was the user's call (non-destructive, CSV-free, PK/FK-safe).
|
|
- **Tests:** migrator unit tests (incl. a column *named* `blob` + a `blob`
|
|
substring in a CHECK left untouched); a **full-stack** integration test
|
|
`tests/it/blob_removal_migration.rs` (v1 blob project → migrate → `text`
|
|
column + row data preserved + `.bak`); a **Tier-4 PTY** end-to-end test
|
|
`e2e_pty::opens_a_legacy_v1_blob_project_by_migrating_to_text` (the real
|
|
binary opens a seeded legacy v1-blob project via `--resume` → migrate +
|
|
rebuild + `text` column) — added in the implementation `/runda` pass to
|
|
cover the runtime's migrate-on-open glue; updated all-types tests to nine;
|
|
regenerated 5 typing-surface snapshots (reviewed — only the `blob`/`data`
|
|
candidate vanished).
|
|
- **Docs:** ADR-0005 Amendment 2 (committed `1a2002d`) + README index; swept
|
|
`ten-type`→`nine-type` / removed `blob` from CLAUDE.md, `requirements.md`,
|
|
the website (`reference/types.md`, the seed doc's stale `not null blob`
|
|
bullet, the `rdbms.mjs` highlight grammar), and the cross-reference counts in
|
|
ADR-0030/0033/0035. CHANGELOG `[Unreleased] → Removed`.
|
|
|
|
## §3. Decisions & notes for next time
|
|
|
|
- **convert-to-text, not drop-the-column** (user, 2026-06-22): drop would force
|
|
rewriting every `data/*.csv` past the rebuild's strict header check — not
|
|
worth it for a few-days-old, few-users tool.
|
|
- **Full v2 framework migration, not parse-time leniency** (user): the proper
|
|
recorded migration with `.bak`, exercising the dormant framework.
|
|
- **`BlobLit` grammar terminal deliberately left** — a pre-existing,
|
|
`#[allow(dead_code)]` speculative token never used by any grammar; orthogonal
|
|
to the type vocabulary. Its "blob literal" string is unreachable. Removing it
|
|
is a separate optional cleanup (touches the grammar core).
|
|
- **Known assumption:** the migrator + `body_declares_blob_column` match the
|
|
serializer's *inline* column format (`- { name: …, type: … }`). A
|
|
hand-written *block-style* `project.yaml` with `type: blob` wouldn't convert
|
|
(and would then fail to parse). `project.yaml` is always machine-serialized
|
|
inline, so this is fine in practice — noted in case a future format change
|
|
moves away from inline columns.
|
|
- **Other ADRs (0030/0035) keep their historical `blob` content** (type-change
|
|
matrix, `binary`/`varbinary` aliases) per the project's supersede-don't-rewrite
|
|
ADR philosophy; ADR-0005 Amendment 2 is the authoritative record.
|
|
|
|
## §4. Process pins / next
|
|
|
|
- Commits user-confirmed, no AI attribution, append-only, on `main`; **push is
|
|
the user's step** (everything this session is unpushed).
|
|
- **`/runda` was run on both the ADR (design) and the implementation.** The
|
|
implementation pass found one real gap — the runtime's migrate-on-open glue
|
|
was untested — closed with the new Tier-4 PTY test. It also verified the
|
|
import path migrates (extract→migrate→rebuild) and the non-migration
|
|
`parse_schema` callers fail-safe.
|
|
- Proposed commit split for the implementation: (1) `feat(types)!` — code +
|
|
tests + CHANGELOG; (2) `docs` — the CLAUDE.md/requirements/website/ADR-x-ref
|
|
sweep; (3) `docs(handoff-79)`.
|
|
- Consider a `cargo sweep` at this milestone.
|
|
- **Next open issues:** #37 (clause hints, on-mission), #38 (escalate
|
|
do/defer/close first), #40 (winget release notes). Plus: blob removal means a
|
|
`cargo sweep`-worthy build and a good moment to push.
|