diff --git a/docs/spec-implementation-audit.md b/docs/spec-implementation-audit.md deleted file mode 100644 index e1e406b..0000000 --- a/docs/spec-implementation-audit.md +++ /dev/null @@ -1,176 +0,0 @@ -# Spec ⇄ Implementation Audit - -> Generated 2026-06-07 against `main` @ `807d3c8` (version 0.1.0). -> Method: one read-only auditor per spec section (00–10) classified every discrete -> requirement, then an adversarial verify pass re-checked each claimed gap to refute -> false negatives. Baseline at audit time: **`typecheck` clean, 470 tests passing (40 files)**. - -## Verdict - -Astrolabe is **substantially complete against its own spec**. Across the 11 spec sections, -**320 of 344 discrete requirements are fully implemented** (93%). Of the remaining 24: - -- **16 are deferred-by-plan** to M6 (the milestone in progress) — planned, not forgotten. -- **3 are genuine gaps** the plan does _not_ account for (one missing feature, one - divergence, one partial animation). -- **3 are partials** that are really "core done, UI deferred to M6." -- **2 are documented/intentional divergences** (Settings architecture) — these are - **spec drift to reconcile**, not implementation bugs. - -The MVP loop (M1) and everything through M5 is solid. The only work that escapes the M6 -net is small and listed under **Verified gaps** below. - -## Scorecard - -| § | Section | State | impl | gaps (non-impl) | -| --- | ------------------------ | ----------- | ---- | ------------------------------------- | -| 00 | Product Overview | ✅ complete | 28 | — | -| 01 | Application Shell & Nav | 🟢 mostly | 27 | 3 partial · 1 deferred · 1 diverges | -| 02 | Snippet Library | 🟡 partial | 28 | 11 deferred (search/sort/storage-mon) | -| 03 | Editor & Draft/Published | 🟢 mostly | 38 | **1 missing (auto-format)** | -| 04 | Live Preview | 🟢 mostly | 31 | 1 deferred (busy indicator) | -| 05 | Datasets | ✅ complete | 31 | **1 diverges (Save not disabled)** | -| 06 | Chart Builder | ✅ complete | 25 | — | -| 07 | Settings | ✅ complete | 27 | — | -| 08 | Import & Export | 🟢 mostly | 33 | 1 deferred (atomic rollback on quota) | -| 09 | Data Model & Persistence | 🟡 partial | 18 | 1 deferred (sort preference §09D) | -| 10 | Non-Functional | 🟡 partial | 34 | 2 partial · 1 deferred | - -`partial` totals are concentrated in §10 because they reflect "infrastructure built, M6 UI -pending" rather than absent capability. - ---- - -## Verified gaps (NOT covered by the M6 plan) - -These survived the adversarial verify pass and have **no deferral note** in -`IMPLEMENTATION-PLAN.md`. Worth a decision now. - -### 1. §03A — Automatic JSON reformatting on type/paste · **MISSING** - -Spec §03A requires that pasting and typing trigger automatic reformatting so JSON stays -consistently indented. **No document-formatting provider is registered anywhere in `src/`.** -The editor buffers raw text as-typed; only programmatic rewrites (Extract) emit pretty JSON -via `JSON.stringify(…, null, 2)`. - -- M2 is marked **complete**, and `architecture/08` explicitly lists the formatter in the M2 - borrow list (`json-stringify-pretty-compact` format action) — so this was scoped for M2 - and dropped, not deferred. -- Evidence: `SpecEditor.tsx:264-267` (raw `getValue()`, no format); `monaco-schema.ts` - registers diagnostics only; `grep registerDocumentFormattingEditProvider` → no hits. -- **Decision needed:** implement the formatter (small, self-contained), or amend §03A / - `architecture/08` to drop the requirement if auto-reformat-on-type is no longer wanted. - -### 2. §05 — Dataset Save button not disabled until valid · **DIVERGES** - -Spec §05 says Save is disabled until a name and valid data/URL are present. Implementation -keeps the button always clickable and validates **on submit** (`save()` returns `false`, -sets `formError`). Functionally safe, but the spec'd affordance (disabled state) never -appears. No deferral note exists. - -- Evidence: `DatasetsModal.tsx:436` (no `disabled`); contrast `ChartBuilderModal.tsx:483` - which already does `disabled={!valid}` — the precedent/pattern exists in-repo. -- **Decision needed:** cheap to align (derive a `canSave` from the existing validation), or - accept submit-time validation and note it in §05. - -### 3. §01F — Toast fade-**out** missing · **PARTIAL** - -Spec §01F: toasts "appear/disappear with a brief fade." Toasts fade **in** (`@keyframes -toast-in`, reduced-motion respected) but on dismiss are removed from the store immediately — -React unmounts with no fade-**out**. - -- Evidence: `Toaster.module.css:62-71` (in only); `NotificationStore.ts:77` (immediate - filter-out); `Toaster.tsx:57` (timeout → immediate `dismiss`). -- This is M6 polish territory but isn't itemized in the M6 list. Add an exit animation - (delay-before-removal or `AnimatePresence`-style pattern). - ---- - -## Spec drift to reconcile (not a code bug) - -### §01B/§01C vs §07 — Settings: modal or popover? - -`§01B` (header entry points) and `§01C` (modal set) still describe **Settings as a header -button opening a modal**. `§07` and `architecture/10` deliberately redesigned Settings into -**distributed, live-applied per-pane disclosure popovers** (no modal, no header button), and -the implementation correctly follows §07: - -- `modal-registry.ts:14-16` — "Settings is deliberately NOT a modal" -- `EventRouter.ts:91-98` — `Cmd/Ctrl+,` opens the editor settings **popover**, not a modal -- `App.tsx:67-102` — header has Datasets/Import/Export but **no Settings button** - -The code is right; **the spec is internally inconsistent.** Action: update §01B/§01C to -match the §07 distributed-settings decision (per AGENTS.md "fix spec/code drift -immediately"). Same note applies to the §01C modal set still listing Settings. - ---- - -## Deferred to M6 (planned — informational) - -All of the following are explicitly deferred in `IMPLEMENTATION-PLAN.md`. They are the real -remaining M6 surface area: - -| Area | Spec | State | -| --------------------------------------- | --------- | ------------------------------------------------------------------- | -| **Search** (filter, clear, scope) | §02 | not started; 5 sub-reqs | -| **Sort** controls + persistence | §02, §09D | hardcoded modified/desc (= spec default); no UI / no `ux-prefs` key | -| Two distinct empty-state messages | §02 | single message; tied to search | -| **Storage Monitor** UI | §02, §10 | **core + adapter done & tested** (`storage-estimate`); no component | -| Quota-failure save warning (UI) | §02, §10 | error→toast path exists; no monitor UI | -| Render **busy indicator** (>~1s) | §04, §10 | non-blocking render done; overlay + `aria-busy` deferred (TODO) | -| Atomic rollback on quota during import | §08 | warns on overage; no hard-fail rollback (TODO `transfer.ts:135`) | -| **About & Privacy** + **Donate** modals | §01 | typed in `ModalName`, no components/registry entries | -| Offline/PWA manual verification | §10 | configured (`registerType:'prompt'`); not yet manually verified | - -Note the Storage Monitor and sort are "groundwork landed, UI pending" — the core logic ships -and is tested (e.g. `storage-estimate.test.ts`), so M6 is wiring, not building from zero. - ---- - -## Section detail - -- **§00 Product Overview — complete.** Every overview claim (local-first, no account, JSON - editing, live preview, reusable datasets, draft/published, import/export, three-pane + - modals) maps to shipped code. -- **§01 Shell — mostly complete.** Three-pane layout, resize handles, toggle strip (a11y), - keyboard router, URL routing w/ back-forward, toasts, modal system all present. Gaps: - About/Donate modals (deferred), toast fade-out (partial), Settings-modal drift. -- **§02 Snippet Library — partial.** List, list-item (status + linked datasets), metadata - panel (rename/comment/timestamps), create/duplicate/delete, naming, first-run onboarding - canvas (welcome + example gallery, replacing the old placeholder seed), and the list's - no-search-matches empty state all done. Deferred: search, sort UI+persistence, storage monitor. -- **§03 Editor — mostly complete.** Draft/Published, auto-save, debounced auto-render, - publish/revert + confirm, inline errors, Extract-to-Dataset all working. Gap: - auto-reformat-on-type (**missing**, see above). -- **§04 Live Preview — mostly complete.** Rendering contract (ref resolution + fit-mode, - recursive, tested), empty/error handling, tailored dataset-not-found message, responsive - resize. Deferred: >1s busy indicator. -- **§05 Datasets — complete.** Two-pane modal, profile inference, ref resolution, - bidirectional links, extract flow. Minor divergence: Save not disabled-until-valid. -- **§06 Chart Builder — complete.** Five marks, four channels, Tier-B smart defaults + - guards, channel transforms (aggregate/bin/timeUnit), sort/stacking, pre-population, - validation, live preview, snippet creation + linking. Matches research doc intent. -- **§07 Settings — complete.** Three clusters as distributed disclosure popovers, live - apply, theme header toggle, `Cmd/Ctrl+,`, localStorage load-with-fallback, hydrate before - paint. -- **§08 Import/Export — mostly complete.** Envelope build, shape detection, normalization, - merge/collision/auto-suffix, feedback messaging — all tested. Deferred: atomic rollback on - quota. -- **§09 Data Model — partial.** Snippet/Dataset/UserSettings schemas with versioned - read-time migrations; storage tiers separated; `datasetRefs` relationships. Deferred: sort - preference (§09D) — only panel layout (widths/visibility) persisted today. -- **§10 Non-Functional — partial.** Keyboard routing, focus management, modal behavior, - reduced-motion, debouncing, error→toast safety all comprehensive. Partial/deferred: - storage-monitor warnings, >1s busy indicator, offline manual verification. - ---- - -## Suggested next actions - -1. **Reconcile §01 spec drift** with §07 (settings-as-popovers) — pure doc fix, do now. -2. **Decide §03A auto-format** — implement (small) or amend the spec; it's the only true - "marked-complete-but-missing" item. -3. **Align §05 Save-disabled** using the existing `ChartBuilderModal` pattern (cheap). -4. **Proceed with M6** for the rest — search, sort, storage-monitor UI, About/Donate, - toast fade-out, busy indicator, atomic rollback, offline verification. Most have core - groundwork already landed.