# Astrolabe — Architecture Playbook

> These documents capture the **architectural patterns** Astrolabe is built on. They are
> self-contained: everything needed to implement a pattern lives here, in Astrolabe's own
> domain terms (snippets, datasets, settings, Vega-Lite specs). You do not need any other
> repository to work from them.
>
> They are the architectural counterpart to [`docs/spec/`](../spec/): the **spec** says
> _what the app does_ (behavior, acceptance points); this **playbook** says _how we build
> it_ (state, persistence, modals, routing, rendering, inference, relationships, and the
> visual + interaction language).

## Spec vs playbook: cite, don't restate

The two documents overlap most in §09 (visual) and §10 (interaction), which necessarily talk
about user-facing widgets. At that overlap, one rule keeps them from drifting:

- The **spec owns product behavior** — what features exist, what surfaces appear when, what
  the data does. The **playbook owns the _how_** — state shape, persistence, ARIA roles,
  keyboard models, focus, tokens, motion.
- **For product behavior, the spec is the source: cite it (`spec §NN`), don't restate it,
  and never contradict it.** A playbook bullet may _name_ the behavior in one clause and cite
  the spec, then spend its words on the _how_ (the role, the keys, the focus move) and the
  _why_ (the council/canon citation). When a playbook bullet and the spec disagree, the
  **spec wins** and the bullet is the bug. Restatement is the leak: two docs describing the
  same behavior in their own words drift into contradiction; one cites the other instead.

## How to use this playbook

- Building a feature? Read the relevant spec section first (the _what_), then the matching
  playbook doc (the _how_), then implement core-first per [`../IMPLEMENTATION-PLAN.md`](../IMPLEMENTATION-PLAN.md).
- Each doc states the pattern, the **rationale** (what problem it solves, what it prevents),
  TypeScript sketches in Astrolabe terms, and Do/Don't rules.
- The sketches are _illustrative_, not finished code. Adapt them; keep the principles.

## The documents

| #   | Doc                                                             | Covers                                                                                                                                                                                                                                                                                                                                                                    |
| --- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 01  | [State & Stores](01-state-and-stores.md)                        | Zustand stores; one source of truth; selector derivations; central `useAppStore` vs per-feature stores; testable action functions; debounced auto-save.                                                                                                                                                                                                                   |
| 02  | [Persistence](02-persistence.md)                                | The infrastructure-adapter boundary; promise-wrapped IndexedDB wrapper; lazy data loading; per-record schema versioning + migration; localStorage prefs with fallback; storage tiers + quota monitoring.                                                                                                                                                                  |
| 03  | [Modal System](03-modal-system.md)                              | Registry + coordinator + shell; one modal at a time; unsaved-change detection via snapshot; focus trap; backdrop/Escape/close dismissal.                                                                                                                                                                                                                                  |
| 04  | [Routing & Events](04-routing-and-events.md)                    | URL hash as view-state (restore/sync, Back/Forward); global keyboard routing; Escape priority chain; the single-source `isInInteractiveContext()` helper (Monaco-aware).                                                                                                                                                                                                  |
| 05  | [Rendering, Theming & Preview](05-rendering-theming-preview.md) | vega-embed integration (`actions:false`, `view.finalize()`); field-name escaping; theme→config mapping; debounced non-blocking renderer; resilient error display.                                                                                                                                                                                                         |
| 06  | [Type Inference & Profiling](06-type-inference.md)              | Pure, portable column-type inference (number/text/date/boolean) and the dataset profile shape.                                                                                                                                                                                                                                                                            |
| 07  | [Naming & Relationships](07-naming-and-relationships.md)        | Unique-name enforcement + import auto-suffix; the bidirectional snippet↔dataset name link; rename propagation into specs.                                                                                                                                                                                                                                                 |
| 08  | [vega/editor Techniques](08-vega-editor-techniques.md)          | Reference brief: borrowable Monaco-schema wiring, vega-embed lifecycle, two-tier validation, and data-flow/debounce techniques distilled from the official Vega-Lite editor — plus where we do better, and our editor-augmentation layer (structural transforms + data-aware hints).                                                                                      |
| 09  | [Visual Design Language](09-visual-design.md)                   | The _visual_ contract: principles inspired by IBM/Carbon, deliberate divergences (square chrome, free color/theming), the token system (Plex type, 8px spacing, role-based color, motion), component conventions, and where to mine the Carbon/IBM source repos for more. Companion: [`visual-specimen.html`](visual-specimen.html).                                      |
| 10  | [Interaction & Feedback](10-interaction-and-feedback.md)        | The _interaction_ contract: the feedback-channel decision table, latency/feedback budgets, the non-happy-path triad, the recovery & data-safety contract, the keyboard/focus contract, and the resolved widget patterns (window splitter, toolbar, segmented controls, selectable lists, search, sort, empty states, modals). Cites `spec/` for behavior; owns the _how_. |
| 11  | [Learning Section](11-learning-section.md)                      | The `/learn/` deep-dive: a marketing-surface Vite entry reusing core + the landing chart embed; markdown-authored lessons (`import.meta.glob`) parsed into an ordered block model; the authoring/engine split (pure parser in core; `marked` only in `src/learn`).                                                                                                        |

## The non-negotiable layering (every doc assumes this)

- **`src/core/`** — portable, pure logic. No browser APIs, no React, no Monaco. Spec
  operations live here and are unit-tested hardest. (Docs 06, 07, parts of 05 land here.)
- **`src/app/stores/`** — Zustand stores. (Doc 01.)
- **`src/app/infrastructure/`** — the _only_ place that touches `indexedDB`, `localStorage`,
  or `window.location`. Everything else goes through these typed adapters. (Docs 02, 04.)
- **`src/app/services/` & `orchestration/`** — coordination that composes stores +
  infrastructure + core (lifecycle, routing sync, dependency upkeep). (Docs 03, 04, 07.)
- **`src/app/components/`** — React + CSS Modules. Thin; pushes logic down into stores/core
  so it stays testable. (Docs 03, 05.)

## Why a playbook at all

Patterns written down once, in one place, stop two classes of problem: drift (the same
decision re-litigated inconsistently across features) and rediscovery (re-deriving why
something is the way it is). When a pattern here proves wrong, change the doc — don't fork
the convention silently. This is the same discipline `docs/spec/` applies to behavior.
